actions-runner-controller/github/actions/multi_client.go

103 lines
2.5 KiB
Go

package actions
import (
"context"
"fmt"
"sync"
"github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1/appconfig"
"github.com/go-logr/logr"
)
type MultiClient interface {
GetClientFor(ctx context.Context, githubConfigURL string, appConfig *appconfig.AppConfig, namespace string, options ...ClientOption) (ActionsService, error)
}
type multiClient struct {
// To lock adding and removing of individual clients.
mu sync.Mutex
clients map[ActionsClientKey]*Client
logger logr.Logger
}
type GitHubAppAuth struct {
// AppID is the ID or the Client ID of the application
AppID string
AppInstallationID int64
AppPrivateKey string
}
type ActionsAuth struct {
// GitHub App
AppCreds *GitHubAppAuth
// GitHub PAT
Token string
}
type ActionsClientKey struct {
Identifier string
Namespace string
}
func NewMultiClient(logger logr.Logger) MultiClient {
return &multiClient{
mu: sync.Mutex{},
clients: make(map[ActionsClientKey]*Client),
logger: logger,
}
}
func (m *multiClient) GetClientFor(ctx context.Context, githubConfigURL string, appConfig *appconfig.AppConfig, namespace string, options ...ClientOption) (ActionsService, error) {
m.logger.Info("retrieve actions client", "githubConfigURL", githubConfigURL, "namespace", namespace)
if err := appConfig.Validate(); err != nil {
return nil, fmt.Errorf("failed to validate app config: %w", err)
}
var creds ActionsAuth
if len(appConfig.Token) > 0 {
creds.Token = appConfig.Token
} else {
creds.AppCreds = &GitHubAppAuth{
AppID: appConfig.AppID,
AppInstallationID: appConfig.AppInstallationID,
AppPrivateKey: appConfig.AppPrivateKey,
}
}
client, err := NewClient(
githubConfigURL,
&creds,
append([]ClientOption{
WithLogger(m.logger),
}, options...)...,
)
if err != nil {
return nil, fmt.Errorf("failed to instantiate new client: %w", err)
}
m.mu.Lock()
defer m.mu.Unlock()
key := ActionsClientKey{
Identifier: client.Identifier(),
Namespace: namespace,
}
cachedClient, has := m.clients[key]
if has && cachedClient.rootCAs.Equal(client.rootCAs) {
m.logger.Info("using cache client", "githubConfigURL", githubConfigURL, "namespace", namespace)
return cachedClient, nil
}
m.logger.Info("creating new client", "githubConfigURL", githubConfigURL, "namespace", namespace)
m.clients[key] = client
m.logger.Info("successfully created new client", "githubConfigURL", githubConfigURL, "namespace", namespace)
return client, nil
}