mirror of https://github.com/k3s-io/k3s
vSphere: add token auth support for tags client
SAML auth support for the vCenter rest API endpoint came to govmomi a bit after Zone support came to vSphere Cloud Provider. Fixes #75511pull/564/head
parent
d35c86fd8a
commit
fdd0a45232
|
@ -86,34 +86,27 @@ func (connection *VSphereConnection) Connect(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// login calls SessionManager.LoginByToken if certificate and private key are configured,
|
||||
// otherwise calls SessionManager.Login with user and password.
|
||||
func (connection *VSphereConnection) login(ctx context.Context, client *vim25.Client) error {
|
||||
m := session.NewManager(client)
|
||||
connection.credentialsLock.Lock()
|
||||
defer connection.credentialsLock.Unlock()
|
||||
|
||||
// Signer returns an sts.Signer for use with SAML token auth if connection is configured for such.
|
||||
// Returns nil if username/password auth is configured for the connection.
|
||||
func (connection *VSphereConnection) Signer(ctx context.Context, client *vim25.Client) (*sts.Signer, error) {
|
||||
// TODO: Add separate fields for certificate and private-key.
|
||||
// For now we can leave the config structs and validation as-is and
|
||||
// decide to use LoginByToken if the username value is PEM encoded.
|
||||
b, _ := pem.Decode([]byte(connection.Username))
|
||||
if b == nil {
|
||||
klog.V(3).Infof("SessionManager.Login with username '%s'", connection.Username)
|
||||
return m.Login(ctx, neturl.UserPassword(connection.Username, connection.Password))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
klog.V(3).Infof("SessionManager.LoginByToken with certificate '%s'", connection.Username)
|
||||
|
||||
cert, err := tls.X509KeyPair([]byte(connection.Username), []byte(connection.Password))
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to load X509 key pair. err: %+v", err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tokens, err := sts.NewClient(ctx, client)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to create STS client. err: %+v", err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := sts.TokenRequest{
|
||||
|
@ -123,9 +116,31 @@ func (connection *VSphereConnection) login(ctx context.Context, client *vim25.Cl
|
|||
signer, err := tokens.Issue(ctx, req)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to issue SAML token. err: %+v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return signer, nil
|
||||
}
|
||||
|
||||
// login calls SessionManager.LoginByToken if certificate and private key are configured,
|
||||
// otherwise calls SessionManager.Login with user and password.
|
||||
func (connection *VSphereConnection) login(ctx context.Context, client *vim25.Client) error {
|
||||
m := session.NewManager(client)
|
||||
connection.credentialsLock.Lock()
|
||||
defer connection.credentialsLock.Unlock()
|
||||
|
||||
signer, err := connection.Signer(ctx, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if signer == nil {
|
||||
klog.V(3).Infof("SessionManager.Login with username %q", connection.Username)
|
||||
return m.Login(ctx, neturl.UserPassword(connection.Username, connection.Password))
|
||||
}
|
||||
|
||||
klog.V(3).Infof("SessionManager.LoginByToken with certificate %q", connection.Username)
|
||||
|
||||
header := soap.Header{Security: signer}
|
||||
|
||||
return m.LoginByToken(client.WithHeader(ctx, header))
|
||||
|
|
|
@ -38,7 +38,7 @@ import (
|
|||
"github.com/vmware/govmomi/vapi/tags"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
vmwaretypes "github.com/vmware/govmomi/vim25/types"
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
k8stypes "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/informers"
|
||||
|
@ -1432,10 +1432,20 @@ func (vs *VSphere) NodeManager() (nodeManager *NodeManager) {
|
|||
|
||||
func withTagsClient(ctx context.Context, connection *vclib.VSphereConnection, f func(c *rest.Client) error) error {
|
||||
c := rest.NewClient(connection.Client)
|
||||
user := url.UserPassword(connection.Username, connection.Password)
|
||||
if err := c.Login(ctx, user); err != nil {
|
||||
signer, err := connection.Signer(ctx, connection.Client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if signer == nil {
|
||||
user := url.UserPassword(connection.Username, connection.Password)
|
||||
err = c.Login(ctx, user)
|
||||
} else {
|
||||
err = c.LoginByToken(c.WithSigner(ctx, signer))
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := c.Logout(ctx); err != nil {
|
||||
klog.Errorf("failed to logout: %v", err)
|
||||
|
|
|
@ -344,6 +344,10 @@ func TestZones(t *testing.T) {
|
|||
cfg, cleanup := configFromSim()
|
||||
defer cleanup()
|
||||
|
||||
// Configure for SAML token auth
|
||||
cfg.Global.User = localhostCert
|
||||
cfg.Global.Password = localhostKey
|
||||
|
||||
// Create vSphere configuration object
|
||||
vs, err := newControllerNode(cfg)
|
||||
if err != nil {
|
||||
|
@ -382,8 +386,11 @@ func TestZones(t *testing.T) {
|
|||
|
||||
// Tag manager instance
|
||||
m := tags.NewManager(rest.NewClient(vsi.conn.Client))
|
||||
user := url.UserPassword(vsi.conn.Username, vsi.conn.Password)
|
||||
if err = m.Login(ctx, user); err != nil {
|
||||
signer, err := vsi.conn.Signer(ctx, vsi.conn.Client)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = m.LoginByToken(m.WithSigner(ctx, signer)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue