Skip to content

Commit

Permalink
fix(platform): log failed for user impersonation (#1662)
Browse files Browse the repository at this point in the history
  • Loading branch information
leoryu authored Nov 18, 2021
1 parent a5e246c commit fa659cb
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 103 deletions.
23 changes: 23 additions & 0 deletions api/platform/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/rest"
applicationv1 "tkestack.io/tke/api/application/v1"
)

Expand Down Expand Up @@ -376,6 +377,28 @@ func (i ImpersonateUserExtra) ExtraToHeaders() map[string][]string {
return res
}

func (cc ClusterCredential) RESTConfig() *rest.Config {
config := &rest.Config{}
if cc.CACert != nil {
config.TLSClientConfig.CAData = cc.CACert
} else {
config.TLSClientConfig.Insecure = true
}
if cc.ClientCert != nil && cc.ClientKey != nil {
config.TLSClientConfig.CertData = cc.ClientCert
config.TLSClientConfig.KeyData = cc.ClientKey
}
if cc.Token != nil {
config.BearerToken = *cc.Token
}

config.Impersonate.UserName = cc.Impersonate
config.Impersonate.Groups = cc.ImpersonateGroups
config.Impersonate.Extra = cc.ImpersonateUserExtra.ExtraToHeaders()

return config
}

// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

Expand Down
23 changes: 23 additions & 0 deletions api/platform/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/rest"
applicationv1 "tkestack.io/tke/api/application/v1"
)

Expand Down Expand Up @@ -382,6 +383,28 @@ func (i ImpersonateUserExtra) ExtraToHeaders() map[string][]string {
return res
}

func (cc ClusterCredential) RESTConfig() *rest.Config {
config := &rest.Config{}
if cc.CACert != nil {
config.TLSClientConfig.CAData = cc.CACert
} else {
config.TLSClientConfig.Insecure = true
}
if cc.ClientCert != nil && cc.ClientKey != nil {
config.TLSClientConfig.CertData = cc.ClientCert
config.TLSClientConfig.KeyData = cc.ClientKey
}
if cc.Token != nil {
config.BearerToken = *cc.Token
}

config.Impersonate.UserName = cc.Impersonate
config.Impersonate.Groups = cc.ImpersonateGroups
config.Impersonate.Extra = cc.ImpersonateUserExtra.ExtraToHeaders()

return config
}

// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

Expand Down
50 changes: 5 additions & 45 deletions pkg/logagent/util/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,16 @@ package util

import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"net"
"net/http"
"net/url"
"sync"
"time"

"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"

platformversionedclient "tkestack.io/tke/api/client/clientset/versioned/typed/platform/v1"
platformv1 "tkestack.io/tke/api/platform/v1"
Expand Down Expand Up @@ -127,49 +124,12 @@ func GetClusterPodIP(ctx context.Context, clusterName, namespace, podName string
// BuildTransport create the http transport for communicate to backend
// kubernetes api server.
func BuildTransportV1(credential *platformv1.ClusterCredential) (http.RoundTripper, error) {
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
}
if len(credential.CACert) > 0 {
transport.TLSClientConfig = &tls.Config{
RootCAs: rootCertPool(credential.CACert),
}
} else {
transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
}
}
config := credential.RESTConfig()

if credential.ClientKey != nil && credential.ClientCert != nil {
cert, err := tls.X509KeyPair(credential.ClientCert, credential.ClientKey)
if err != nil {
return nil, err
}
transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
transport, err := restclient.TransportFor(config)
if err != nil {
return nil, err
}

return transport, nil
}

// rootCertPool returns nil if caData is empty. When passed along, this will mean "use system CAs".
// When caData is not empty, it will be the ONLY information used in the CertPool.
func rootCertPool(caData []byte) *x509.CertPool {
// What we really want is a copy of x509.systemRootsPool, but that isn't exposed. It's difficult to build (see the go
// code for a look at the platform specific insanity), so we'll use the fact that RootCAs == nil gives us the system values
// It doesn't allow trusting either/or, but hopefully that won't be an issue
if len(caData) == 0 {
return nil
}

// if we have caData, use it
certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(caData)
return certPool
}
10 changes: 5 additions & 5 deletions pkg/platform/proxy/core/pod/storage/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ package storage
import (
"context"
"fmt"
"net/url"
"strconv"
"time"

corev1api "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
genericrest "k8s.io/apiserver/pkg/registry/generic/rest"
"k8s.io/apiserver/pkg/registry/rest"
"net/url"
"strconv"
"time"
platforminternalclient "tkestack.io/tke/api/client/clientset/internalversion/typed/platform/internalversion"
"tkestack.io/tke/pkg/platform/util"
restutil "tkestack.io/tke/pkg/platform/util/rest"
Expand Down Expand Up @@ -87,7 +88,7 @@ func (r *LogREST) Get(ctx context.Context, name string, opts runtime.Object) (ru
return nil, errors.NewInvalid(corev1api.SchemeGroupVersion.WithKind("PodLogOptions").GroupKind(), name, errs)
}

location, transport, token, err := util.APIServerLocation(ctx, r.platformClient)
location, transport, _, err := util.APIServerLocation(ctx, r.platformClient)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -121,7 +122,6 @@ func (r *LogREST) Get(ctx context.Context, name string, opts runtime.Object) (ru
location.RawQuery = params.Encode()

return &restutil.LocationStreamer{
Token: token,
Location: location,
Transport: transport,
ContentType: "text/plain",
Expand Down
1 change: 1 addition & 0 deletions pkg/platform/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func (c *Cluster) setRESTConfigDefaults(config *rest.Config) error {

func (c *Cluster) RESTConfig(config *rest.Config) (*rest.Config, error) {
err := c.setRESTConfigDefaults(config)
c.ClusterCredential.RESTConfig()
if err != nil {
return nil, err
}
Expand Down
48 changes: 4 additions & 44 deletions pkg/platform/util/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,13 @@ package util

import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"math/rand"
"net"
"net/http"
"path"
"reflect"
"strings"
"time"

monitoringclient "github.com/coreos/prometheus-operator/pkg/client/versioned"
mapset "github.com/deckarep/golang-set"
Expand Down Expand Up @@ -123,32 +120,11 @@ func ResourceFromKind(kind string) string {
// BuildTransport create the http transport for communicate to backend
// kubernetes api server.
func BuildTransport(credential *platform.ClusterCredential) (http.RoundTripper, error) {
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
}
if len(credential.CACert) > 0 {
transport.TLSClientConfig = &tls.Config{
RootCAs: rootCertPool(credential.CACert),
}
} else {
transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
}
}
config := credential.RESTConfig()

if credential.ClientKey != nil && credential.ClientCert != nil {
cert, err := tls.X509KeyPair(credential.ClientCert, credential.ClientKey)
if err != nil {
return nil, err
}
transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
transport, err := restclient.TransportFor(config)
if err != nil {
return nil, err
}

return transport, nil
Expand Down Expand Up @@ -519,22 +495,6 @@ func ClusterV1Host(c *platformv1.Cluster) (string, error) {
return ClusterHost(&cluster)
}

// rootCertPool returns nil if caData is empty. When passed along, this will mean "use system CAs".
// When caData is not empty, it will be the ONLY information used in the CertPool.
func rootCertPool(caData []byte) *x509.CertPool {
// What we really want is a copy of x509.systemRootsPool, but that isn't exposed. It's difficult to build (see the go
// code for a look at the platform specific insanity), so we'll use the fact that RootCAs == nil gives us the system values
// It doesn't allow trusting either/or, but hopefully that won't be an issue
if len(caData) == 0 {
return nil
}

// if we have caData, use it
certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(caData)
return certPool
}

func PrepareClusterScale(cluster *platform.Cluster, oldCluster *platform.Cluster) ([]platform.ClusterMachine, error) {
allMachines, scalingMachines := []platform.ClusterMachine{}, []platform.ClusterMachine{}

Expand Down
13 changes: 4 additions & 9 deletions pkg/platform/util/rest/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,20 @@ package rest

import (
"context"
"fmt"
"io"
"net/http"
"net/url"
"strings"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
genericrest "k8s.io/apiserver/pkg/registry/generic/rest"
"k8s.io/apiserver/pkg/registry/rest"
"net/http"
"net/url"
"strings"
)

// LocationStreamer is a resource that streams the contents of a particular
// location URL.
type LocationStreamer struct {
Token string
Location *url.URL
Transport http.RoundTripper
ContentType string
Expand Down Expand Up @@ -84,10 +83,6 @@ func (s *LocationStreamer) InputStream(ctx context.Context, apiVersion, acceptHe
// will be release properly.
req = req.WithContext(ctx)

if s.Token != "" {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", strings.TrimSpace(s.Token)))
}

resp, err := client.Do(req)
if err != nil {
return nil, false, "", err
Expand Down

0 comments on commit fa659cb

Please sign in to comment.