Reduce HTTP client creations in the Keystone connector (#2659)

Signed-off-by: erwinvaneyk <erwinvaneyk@gmail.com>
This commit is contained in:
Erwin van Eyk 2022-09-23 14:02:02 -07:00 committed by GitHub
parent 7b589ba3a7
commit d96f384f2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 28 deletions

View File

@ -18,6 +18,7 @@ type conn struct {
Host string Host string
AdminUsername string AdminUsername string
AdminPassword string AdminPassword string
client *http.Client
Logger log.Logger Logger log.Logger
} }
@ -35,6 +36,7 @@ type domainKeystone struct {
// Config holds the configuration parameters for Keystone connector. // Config holds the configuration parameters for Keystone connector.
// Keystone should expose API v3 // Keystone should expose API v3
// An example config: // An example config:
//
// connectors: // connectors:
// type: keystone // type: keystone
// id: keystone // id: keystone
@ -111,11 +113,12 @@ var (
// Open returns an authentication strategy using Keystone. // Open returns an authentication strategy using Keystone.
func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) {
return &conn{ return &conn{
c.Domain, Domain: c.Domain,
c.Host, Host: c.Host,
c.AdminUsername, AdminUsername: c.AdminUsername,
c.AdminPassword, AdminPassword: c.AdminPassword,
logger, Logger: logger,
client: http.DefaultClient,
}, nil }, nil
} }
@ -192,7 +195,6 @@ func (p *conn) Refresh(
} }
func (p *conn) getTokenResponse(ctx context.Context, username, pass string) (response *http.Response, err error) { func (p *conn) getTokenResponse(ctx context.Context, username, pass string) (response *http.Response, err error) {
client := &http.Client{}
jsonData := loginRequestData{ jsonData := loginRequestData{
auth: auth{ auth: auth{
Identity: identity{ Identity: identity{
@ -221,7 +223,7 @@ func (p *conn) getTokenResponse(ctx context.Context, username, pass string) (res
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
req = req.WithContext(ctx) req = req.WithContext(ctx)
return client.Do(req) return p.client.Do(req)
} }
func (p *conn) getAdminToken(ctx context.Context) (string, error) { func (p *conn) getAdminToken(ctx context.Context) (string, error) {
@ -243,7 +245,6 @@ func (p *conn) checkIfUserExists(ctx context.Context, userID string, token strin
func (p *conn) getUser(ctx context.Context, userID string, token string) (*userResponse, error) { func (p *conn) getUser(ctx context.Context, userID string, token string) (*userResponse, error) {
// https://developer.openstack.org/api-ref/identity/v3/#show-user-details // https://developer.openstack.org/api-ref/identity/v3/#show-user-details
userURL := p.Host + "/v3/users/" + userID userURL := p.Host + "/v3/users/" + userID
client := &http.Client{}
req, err := http.NewRequest("GET", userURL, nil) req, err := http.NewRequest("GET", userURL, nil)
if err != nil { if err != nil {
return nil, err return nil, err
@ -251,7 +252,7 @@ func (p *conn) getUser(ctx context.Context, userID string, token string) (*userR
req.Header.Set("X-Auth-Token", token) req.Header.Set("X-Auth-Token", token)
req = req.WithContext(ctx) req = req.WithContext(ctx)
resp, err := client.Do(req) resp, err := p.client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -276,7 +277,6 @@ func (p *conn) getUser(ctx context.Context, userID string, token string) (*userR
} }
func (p *conn) getUserGroups(ctx context.Context, userID string, token string) ([]string, error) { func (p *conn) getUserGroups(ctx context.Context, userID string, token string) ([]string, error) {
client := &http.Client{}
// https://developer.openstack.org/api-ref/identity/v3/#list-groups-to-which-a-user-belongs // https://developer.openstack.org/api-ref/identity/v3/#list-groups-to-which-a-user-belongs
groupsURL := p.Host + "/v3/users/" + userID + "/groups" groupsURL := p.Host + "/v3/users/" + userID + "/groups"
req, err := http.NewRequest("GET", groupsURL, nil) req, err := http.NewRequest("GET", groupsURL, nil)
@ -285,7 +285,7 @@ func (p *conn) getUserGroups(ctx context.Context, userID string, token string) (
} }
req.Header.Set("X-Auth-Token", token) req.Header.Set("X-Auth-Token", token)
req = req.WithContext(ctx) req = req.WithContext(ctx)
resp, err := client.Do(req) resp, err := p.client.Do(req)
if err != nil { if err != nil {
p.Logger.Errorf("keystone: error while fetching user %q groups\n", userID) p.Logger.Errorf("keystone: error while fetching user %q groups\n", userID)
return nil, err return nil, err

View File

@ -42,8 +42,6 @@ type groupResponse struct {
func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string) { func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string) {
t.Helper() t.Helper()
client := &http.Client{}
jsonData := loginRequestData{ jsonData := loginRequestData{
auth: auth{ auth: auth{
Identity: identity{ Identity: identity{
@ -70,7 +68,7 @@ func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string)
} }
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req) resp, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -93,7 +91,6 @@ func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string)
func createUser(t *testing.T, token, userName, userEmail, userPass string) string { func createUser(t *testing.T, token, userName, userEmail, userPass string) string {
t.Helper() t.Helper()
client := &http.Client{}
createUserData := map[string]interface{}{ createUserData := map[string]interface{}{
"user": map[string]interface{}{ "user": map[string]interface{}{
@ -116,7 +113,7 @@ func createUser(t *testing.T, token, userName, userEmail, userPass string) strin
} }
req.Header.Set("X-Auth-Token", token) req.Header.Set("X-Auth-Token", token)
req.Header.Add("Content-Type", "application/json") req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req) resp, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -139,7 +136,6 @@ func createUser(t *testing.T, token, userName, userEmail, userPass string) strin
// delete group or user // delete group or user
func deleteResource(t *testing.T, token, id, uri string) { func deleteResource(t *testing.T, token, id, uri string) {
t.Helper() t.Helper()
client := &http.Client{}
deleteURI := uri + id deleteURI := uri + id
req, err := http.NewRequest("DELETE", deleteURI, nil) req, err := http.NewRequest("DELETE", deleteURI, nil)
@ -148,7 +144,7 @@ func deleteResource(t *testing.T, token, id, uri string) {
} }
req.Header.Set("X-Auth-Token", token) req.Header.Set("X-Auth-Token", token)
resp, err := client.Do(req) resp, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
t.Fatalf("error: %v", err) t.Fatalf("error: %v", err)
} }
@ -157,7 +153,6 @@ func deleteResource(t *testing.T, token, id, uri string) {
func createGroup(t *testing.T, token, description, name string) string { func createGroup(t *testing.T, token, description, name string) string {
t.Helper() t.Helper()
client := &http.Client{}
createGroupData := map[string]interface{}{ createGroupData := map[string]interface{}{
"group": map[string]interface{}{ "group": map[string]interface{}{
@ -177,7 +172,7 @@ func createGroup(t *testing.T, token, description, name string) string {
} }
req.Header.Set("X-Auth-Token", token) req.Header.Set("X-Auth-Token", token)
req.Header.Add("Content-Type", "application/json") req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req) resp, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -200,14 +195,13 @@ func createGroup(t *testing.T, token, description, name string) string {
func addUserToGroup(t *testing.T, token, groupID, userID string) error { func addUserToGroup(t *testing.T, token, groupID, userID string) error {
t.Helper() t.Helper()
uri := groupsURL + groupID + "/users/" + userID uri := groupsURL + groupID + "/users/" + userID
client := &http.Client{}
req, err := http.NewRequest("PUT", uri, nil) req, err := http.NewRequest("PUT", uri, nil)
if err != nil { if err != nil {
return err return err
} }
req.Header.Set("X-Auth-Token", token) req.Header.Set("X-Auth-Token", token)
resp, err := client.Do(req) resp, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
t.Fatalf("error: %v", err) t.Fatalf("error: %v", err)
} }
@ -219,7 +213,8 @@ func addUserToGroup(t *testing.T, token, groupID, userID string) error {
func TestIncorrectCredentialsLogin(t *testing.T) { func TestIncorrectCredentialsLogin(t *testing.T) {
setupVariables(t) setupVariables(t)
c := conn{ c := conn{
Host: keystoneURL, Domain: testDomain, client: http.DefaultClient,
Host: keystoneURL, Domain: testDomain,
AdminUsername: adminUser, AdminPassword: adminPass, AdminUsername: adminUser, AdminPassword: adminPass,
} }
s := connector.Scopes{OfflineAccess: true, Groups: true} s := connector.Scopes{OfflineAccess: true, Groups: true}
@ -296,7 +291,8 @@ func TestValidUserLogin(t *testing.T) {
defer deleteResource(t, token, userID, usersURL) defer deleteResource(t, token, userID, usersURL)
c := conn{ c := conn{
Host: keystoneURL, Domain: tt.input.domain, client: http.DefaultClient,
Host: keystoneURL, Domain: tt.input.domain,
AdminUsername: adminUser, AdminPassword: adminPass, AdminUsername: adminUser, AdminPassword: adminPass,
} }
s := connector.Scopes{OfflineAccess: true, Groups: true} s := connector.Scopes{OfflineAccess: true, Groups: true}
@ -333,7 +329,8 @@ func TestUseRefreshToken(t *testing.T) {
defer deleteResource(t, token, groupID, groupsURL) defer deleteResource(t, token, groupID, groupsURL)
c := conn{ c := conn{
Host: keystoneURL, Domain: testDomain, client: http.DefaultClient,
Host: keystoneURL, Domain: testDomain,
AdminUsername: adminUser, AdminPassword: adminPass, AdminUsername: adminUser, AdminPassword: adminPass,
} }
s := connector.Scopes{OfflineAccess: true, Groups: true} s := connector.Scopes{OfflineAccess: true, Groups: true}
@ -358,7 +355,8 @@ func TestUseRefreshTokenUserDeleted(t *testing.T) {
userID := createUser(t, token, testUser, testEmail, testPass) userID := createUser(t, token, testUser, testEmail, testPass)
c := conn{ c := conn{
Host: keystoneURL, Domain: testDomain, client: http.DefaultClient,
Host: keystoneURL, Domain: testDomain,
AdminUsername: adminUser, AdminPassword: adminPass, AdminUsername: adminUser, AdminPassword: adminPass,
} }
s := connector.Scopes{OfflineAccess: true, Groups: true} s := connector.Scopes{OfflineAccess: true, Groups: true}
@ -388,7 +386,8 @@ func TestUseRefreshTokenGroupsChanged(t *testing.T) {
defer deleteResource(t, token, userID, usersURL) defer deleteResource(t, token, userID, usersURL)
c := conn{ c := conn{
Host: keystoneURL, Domain: testDomain, client: http.DefaultClient,
Host: keystoneURL, Domain: testDomain,
AdminUsername: adminUser, AdminPassword: adminPass, AdminUsername: adminUser, AdminPassword: adminPass,
} }
s := connector.Scopes{OfflineAccess: true, Groups: true} s := connector.Scopes{OfflineAccess: true, Groups: true}
@ -424,7 +423,8 @@ func TestNoGroupsInScope(t *testing.T) {
defer deleteResource(t, token, userID, usersURL) defer deleteResource(t, token, userID, usersURL)
c := conn{ c := conn{
Host: keystoneURL, Domain: testDomain, client: http.DefaultClient,
Host: keystoneURL, Domain: testDomain,
AdminUsername: adminUser, AdminPassword: adminPass, AdminUsername: adminUser, AdminPassword: adminPass,
} }
s := connector.Scopes{OfflineAccess: true, Groups: false} s := connector.Scopes{OfflineAccess: true, Groups: false}