feat: kubesphere 4.0 (#6115)
* feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> * feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> --------- Signed-off-by: ci-bot <ci-bot@kubesphere.io> Co-authored-by: ks-ci-bot <ks-ci-bot@example.com> Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
committed by
GitHub
parent
b5015ec7b9
commit
447a51f08b
173
vendor/github.com/open-policy-agent/opa/plugins/rest/gcp.go
generated
vendored
Normal file
173
vendor/github.com/open-policy-agent/opa/plugins/rest/gcp.go
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
// Copyright 2020 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultGCPMetadataEndpoint = "http://metadata.google.internal"
|
||||
defaultAccessTokenPath = "/computeMetadata/v1/instance/service-accounts/default/token"
|
||||
defaultIdentityTokenPath = "/computeMetadata/v1/instance/service-accounts/default/identity"
|
||||
)
|
||||
|
||||
// AccessToken holds a GCP access token.
|
||||
type AccessToken struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int64 `json:"expires_in"`
|
||||
TokenType string `json:"token_type"`
|
||||
}
|
||||
|
||||
type gcpMetadataError struct {
|
||||
err error
|
||||
endpoint string
|
||||
statusCode int
|
||||
}
|
||||
|
||||
func (e *gcpMetadataError) Error() string {
|
||||
return fmt.Sprintf("error retrieving gcp ID token from %s %d: %v", e.endpoint, e.statusCode, e.err)
|
||||
}
|
||||
|
||||
func (e *gcpMetadataError) Unwrap() error { return e.err }
|
||||
|
||||
var (
|
||||
errGCPMetadataNotFound = errors.New("not found")
|
||||
errGCPMetadataInvalidRequest = errors.New("invalid request")
|
||||
errGCPMetadataUnexpected = errors.New("unexpected error")
|
||||
)
|
||||
|
||||
// gcpMetadataAuthPlugin represents authentication via GCP metadata service.
|
||||
type gcpMetadataAuthPlugin struct {
|
||||
AccessTokenPath string `json:"access_token_path"`
|
||||
Audience string `json:"audience"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
IdentityTokenPath string `json:"identity_token_path"`
|
||||
Scopes []string `json:"scopes"`
|
||||
}
|
||||
|
||||
func (ap *gcpMetadataAuthPlugin) NewClient(c Config) (*http.Client, error) {
|
||||
if ap.Audience == "" && len(ap.Scopes) == 0 {
|
||||
return nil, errors.New("audience or scopes is required when gcp metadata is enabled")
|
||||
}
|
||||
|
||||
if ap.Audience != "" && len(ap.Scopes) > 0 {
|
||||
return nil, errors.New("either audience or scopes can be set, not both, when gcp metadata is enabled")
|
||||
}
|
||||
|
||||
if ap.Endpoint == "" {
|
||||
ap.Endpoint = defaultGCPMetadataEndpoint
|
||||
}
|
||||
|
||||
if ap.AccessTokenPath == "" {
|
||||
ap.AccessTokenPath = defaultAccessTokenPath
|
||||
}
|
||||
|
||||
if ap.IdentityTokenPath == "" {
|
||||
ap.IdentityTokenPath = defaultIdentityTokenPath
|
||||
}
|
||||
|
||||
t, err := DefaultTLSConfig(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil
|
||||
}
|
||||
|
||||
func (ap *gcpMetadataAuthPlugin) Prepare(req *http.Request) error {
|
||||
var err error
|
||||
var token string
|
||||
|
||||
if ap.Audience != "" {
|
||||
token, err = identityTokenFromMetadataService(ap.Endpoint, ap.IdentityTokenPath, ap.Audience)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving identity token from gcp metadata service: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(ap.Scopes) != 0 {
|
||||
token, err = accessTokenFromMetadataService(ap.Endpoint, ap.AccessTokenPath, ap.Scopes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving access token from gcp metadata service: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %v", token))
|
||||
return nil
|
||||
}
|
||||
|
||||
// accessTokenFromMetadataService returns an access token based on the scopes.
|
||||
func accessTokenFromMetadataService(endpoint, path string, scopes []string) (string, error) {
|
||||
s := strings.Join(scopes, ",")
|
||||
|
||||
e := fmt.Sprintf("%s%s?scopes=%s", endpoint, path, s)
|
||||
|
||||
data, err := gcpMetadataServiceRequest(e)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var accessToken AccessToken
|
||||
err = json.Unmarshal(data, &accessToken)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return accessToken.AccessToken, nil
|
||||
}
|
||||
|
||||
// identityTokenFromMetadataService returns an identity token based on the audience.
|
||||
func identityTokenFromMetadataService(endpoint, path, audience string) (string, error) {
|
||||
e := fmt.Sprintf("%s%s?audience=%s", endpoint, path, audience)
|
||||
|
||||
data, err := gcpMetadataServiceRequest(e)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
func gcpMetadataServiceRequest(endpoint string) ([]byte, error) {
|
||||
request, err := http.NewRequest("GET", endpoint, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request.Header.Add("Metadata-Flavor", "Google")
|
||||
|
||||
timeout := time.Duration(5) * time.Second
|
||||
httpClient := http.Client{Timeout: timeout}
|
||||
|
||||
response, err := httpClient.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
switch s := response.StatusCode; s {
|
||||
case 200:
|
||||
break
|
||||
case 400:
|
||||
return nil, &gcpMetadataError{errGCPMetadataInvalidRequest, endpoint, s}
|
||||
case 404:
|
||||
return nil, &gcpMetadataError{errGCPMetadataNotFound, endpoint, s}
|
||||
default:
|
||||
return nil, &gcpMetadataError{errGCPMetadataUnexpected, endpoint, s}
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
Reference in New Issue
Block a user