103 lines
2.5 KiB
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
|
|
}
|