Skip to content

Commit 1aadbdd

Browse files
committed
Support using serviceaccount on session auth
1 parent c187643 commit 1aadbdd

File tree

6 files changed

+44
-10
lines changed

6 files changed

+44
-10
lines changed

pkg/common/connectionmanager/zones.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ func (cm *ConnectionManager) getDIFromMultiVCorDC(ctx context.Context,
292292

293293
func withTagsClient(ctx context.Context, connection *vclib.VSphereConnection, f func(c *rest.Client) error) error {
294294
c := rest.NewClient(connection.Client)
295-
if connection.SessionManagerURL != "" && connection.SessionManagerToken != "" {
295+
if connection.SessionManagerURL != "" {
296296
c.SessionID(connection.Client.SessionCookie().Value)
297297
return nil
298298
}
@@ -313,7 +313,7 @@ func withTagsClient(ctx context.Context, connection *vclib.VSphereConnection, f
313313

314314
defer func() {
315315
// When using shared session manager we don't need to logout
316-
if connection.SessionManagerURL != "" && connection.SessionManagerToken != "" {
316+
if connection.SessionManagerURL != "" {
317317
return
318318
}
319319

pkg/common/credentialmanager/credentialmanager.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,7 @@ func parseConfig(data map[string][]byte, config map[string]*Credential) error {
303303
}
304304

305305
for vcServer, credential := range config {
306-
if (credential.User == "" || credential.Password == "") &&
307-
(credential.VCSessionManagerURL == "" || credential.VCSessionManagerToken == "") {
306+
if (credential.User == "" || credential.Password == "") && credential.VCSessionManagerURL == "" {
308307

309308
klog.Errorf("Username/Password or shared session manager URL/Token directives are missing for server %s", vcServer)
310309
return ErrCredentialMissing

pkg/common/credentialmanager/credentialmanager_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ func TestParseSecretConfig(t *testing.T) {
394394
VCSessionManagerURL: "https://something.tld/session",
395395
},
396396
},
397-
expectedError: ErrCredentialMissing,
397+
expectedError: nil,
398398
},
399399
{
400400
testName: "Missing session manager url",

pkg/common/vclib/connection.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func (connection *VSphereConnection) login(ctx context.Context, client *vim25.Cl
134134
connection.credentialsLock.Lock()
135135
defer connection.credentialsLock.Unlock()
136136

137-
if connection.SessionManagerURL != "" && connection.SessionManagerToken != "" {
137+
if connection.SessionManagerURL != "" {
138138
token, err := GetSharedToken(ctx, SharedTokenOptions{
139139
URL: connection.SessionManagerURL,
140140
Token: connection.SessionManagerToken,

pkg/common/vclib/vc_session_manager.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import (
77
"encoding/json"
88
"fmt"
99
"net/http"
10+
"os"
1011
"time"
1112
)
1213

14+
const (
15+
saFile = "/var/run/secrets/kubernetes.io/serviceaccount/token"
16+
)
17+
1318
// SharedSessionResponse is the expected structure for a session manager valid
1419
// token response
1520
type SharedSessionResponse struct {
@@ -28,6 +33,8 @@ type SharedTokenOptions struct {
2833
InsecureSkipVerify bool
2934
// Timeout defines the client timeout. Defaults to 5 seconds
3035
Timeout time.Duration
36+
// TokenFile defines a file with token content. Defaults to Kubernetes Service Account file
37+
TokenFile string
3138
}
3239

3340
// GetSharedToken executes an http request on session manager and gets the session manager
@@ -36,8 +43,18 @@ func GetSharedToken(ctx context.Context, options SharedTokenOptions) (string, er
3643
if options.URL == "" {
3744
return "", fmt.Errorf("URL of session manager cannot be empty")
3845
}
46+
47+
if options.TokenFile == "" {
48+
options.TokenFile = saFile
49+
}
50+
51+
// If the token is empty, we should use service account from the Pod instead
3952
if options.Token == "" {
40-
return "", fmt.Errorf("token of session manager cannot be empty")
53+
saValue, err := os.ReadFile(options.TokenFile)
54+
if err != nil {
55+
return "", fmt.Errorf("failed reading token from service account: %w", err)
56+
}
57+
options.Token = string(saValue)
4158
}
4259

4360
timeout := 5 * time.Second

pkg/common/vclib/vc_session_manager_test.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import (
77
"fmt"
88
"net/http"
99
"net/http/httptest"
10+
"os"
1011
"testing"
1112
"time"
1213

1314
"github.com/stretchr/testify/assert"
15+
"github.com/stretchr/testify/require"
1416
"k8s.io/cloud-provider-vsphere/pkg/common/vclib"
1517
)
1618

@@ -74,11 +76,11 @@ func TestGetSharedToken(t *testing.T) {
7476
assert.ErrorContains(t, err, "URL of session manager cannot be empty")
7577
})
7678

77-
t.Run("should fail when no token is passed", func(t *testing.T) {
79+
t.Run("should fail when no token is passed and SA token cannot be read", func(t *testing.T) {
7880
_, err := vclib.GetSharedToken(ctx, vclib.SharedTokenOptions{
79-
URL: "https://some-session-manager.tld/session",
81+
URL: "http://something.tld/lala",
8082
})
81-
assert.ErrorContains(t, err, "token of session manager cannot be empty")
83+
assert.ErrorContains(t, err, "failed reading token from service account: open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file or directory")
8284
})
8385

8486
t.Run("should fail when passed URL is invalid", func(t *testing.T) {
@@ -165,6 +167,22 @@ func TestGetSharedToken(t *testing.T) {
165167
assert.NoError(t, err)
166168
assert.Equal(t, validResponse, token)
167169
})
170+
171+
t.Run("should return a valid token when using a file as a token", func(t *testing.T) {
172+
tokenFile, err := os.CreateTemp("", "")
173+
require.NoError(t, err)
174+
require.NoError(t, tokenFile.Close())
175+
require.NoError(t, os.WriteFile(tokenFile.Name(), []byte(validToken), 0755))
176+
177+
reqURL := fmt.Sprintf("%s/session", server.URL)
178+
token, err := vclib.GetSharedToken(ctx, vclib.SharedTokenOptions{
179+
URL: reqURL,
180+
TrustedCertificates: certpool,
181+
TokenFile: tokenFile.Name(),
182+
})
183+
assert.NoError(t, err)
184+
assert.Equal(t, validResponse, token)
185+
})
168186
})
169187

170188
}

0 commit comments

Comments
 (0)