Skip to content

Commit

Permalink
feat: add agents handling registry auth from license (#510)
Browse files Browse the repository at this point in the history
Signed-off-by: Jakob Steiner <jakob.steiner@glasskube.eu>
  • Loading branch information
kosmoz authored Feb 18, 2025
1 parent f68aeee commit c9ddc78
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 61 deletions.
9 changes: 8 additions & 1 deletion api/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ type AgentResource struct {
Version types.AgentVersion `json:"version"`
}

type AgentRegistryAuth struct {
Username string `json:"username"`
Password string `json:"password"`
}

type AgentDeployment struct {
RevisionID uuid.UUID `json:"revisionId"`
ID uuid.UUID `json:"id"`
RevisionID uuid.UUID `json:"revisionId"`
RegistryAuth map[string]AgentRegistryAuth `json:"registryAuth"`
}

type DockerAgentResource struct {
Expand Down
25 changes: 17 additions & 8 deletions cmd/agent/docker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"syscall"
"time"

"github.com/glasskube/distr/api"
"github.com/glasskube/distr/internal/agentauth"
"github.com/glasskube/distr/internal/agentclient"
"github.com/glasskube/distr/internal/util"
"go.uber.org/zap"
Expand Down Expand Up @@ -82,12 +84,18 @@ loop:
continue
}

reportedStatus, reportedErr := ApplyComposeFile(ctx, resource.Deployment.ComposeFile, resource.Deployment.EnvFile)
if err := client.Status(ctx, resource.Deployment.RevisionID, reportedStatus, reportedErr); err != nil {
logger.Error("failed to send status", zap.Error(err))
var status string
_, err = agentauth.EnsureAuth(ctx, resource.Deployment.AgentDeployment)
if err != nil {
logger.Error("docker auth error", zap.Error(err))
} else {
status, err = ApplyComposeFile(ctx, *resource.Deployment)
}
}

if statusErr := client.Status(ctx, resource.Deployment.RevisionID, status, err); statusErr != nil {
logger.Error("failed to send status", zap.Error(statusErr))
}
}
}
logger.Info("shutting down")
}
Expand Down Expand Up @@ -186,15 +194,15 @@ func ApplyAgentComposeFile(ctx context.Context, manifest map[string]any) error {
return err
}

func ApplyComposeFile(ctx context.Context, composeFileData []byte, envFileData []byte) (string, error) {
func ApplyComposeFile(ctx context.Context, deployment api.DockerAgentDeployment) (string, error) {
var err error
var envFile *os.File
if envFileData != nil {
if deployment.EnvFile != nil {
if envFile, err = os.CreateTemp("", "distr-env"); err != nil {
logger.Error("", zap.Error(err))
return "", fmt.Errorf("failed to create env file in tmp directory: %w", err)
} else {
if _, err = envFile.Write(envFileData); err != nil {
if _, err = envFile.Write(deployment.EnvFile); err != nil {
logger.Error("", zap.Error(err))
return "", fmt.Errorf("failed to write env file: %w", err)
}
Expand All @@ -214,7 +222,8 @@ func ApplyComposeFile(ctx context.Context, composeFileData []byte, envFileData [
composeArgs = append(composeArgs, "-f", "-", "up", "-d", "--quiet-pull")

cmd := exec.CommandContext(ctx, "docker", composeArgs...)
cmd.Stdin = bytes.NewReader(composeFileData)
cmd.Stdin = bytes.NewReader(deployment.ComposeFile)
cmd.Env = append(os.Environ(), agentauth.DockerConfigEnv(deployment.AgentDeployment)...)

var cmdOut []byte
cmdOut, err = cmd.CombinedOutput()
Expand Down
35 changes: 25 additions & 10 deletions cmd/agent/kubernetes/helm_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/glasskube/distr/api"
"github.com/glasskube/distr/internal/agentauth"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
Expand All @@ -21,13 +22,19 @@ var (
helmActionConfigCache = make(map[string]*action.Configuration)
)

func GetHelmActionConfig(namespace string) (*action.Configuration, error) {
func GetHelmActionConfig(
ctx context.Context,
namespace string,
deployment api.AgentDeployment,
) (*action.Configuration, error) {
if cfg, ok := helmActionConfigCache[namespace]; ok {
return cfg, nil
}

var cfg action.Configuration
if rc, err := registry.NewClient(); err != nil {
if authorizer, err := agentauth.EnsureAuth(ctx, deployment); err != nil {
return nil, err
} else if rc, err := registry.NewClient(registry.ClientOptAuthorizer(authorizer)); err != nil {
return nil, err
} else {
cfg.RegistryClient = rc
Expand All @@ -44,13 +51,17 @@ func GetHelmActionConfig(namespace string) (*action.Configuration, error) {
}
}

func GetLatestHelmRelease(namespace, releaseName string) (*release.Release, error) {
cfg, err := GetHelmActionConfig(namespace)
func GetLatestHelmRelease(
ctx context.Context,
namespace string,
deployment api.KubernetesAgentDeployment,
) (*release.Release, error) {
cfg, err := GetHelmActionConfig(ctx, namespace, deployment.AgentDeployment)
if err != nil {
return nil, err
}
historyAction := action.NewHistory(cfg)
if releases, err := historyAction.Run(releaseName); err != nil {
if releases, err := historyAction.Run(deployment.ReleaseName); err != nil {
return nil, err
} else {
return releases[len(releases)-1], nil
Expand Down Expand Up @@ -82,7 +93,7 @@ func RunHelmInstall(
namespace string,
deployment api.KubernetesAgentDeployment,
) (*AgentDeployment, error) {
config, err := GetHelmActionConfig(namespace)
config, err := GetHelmActionConfig(ctx, namespace, deployment.AgentDeployment)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -112,7 +123,7 @@ func RunHelmUpgrade(
namespace string,
deployment api.KubernetesAgentDeployment,
) (*AgentDeployment, error) {
cfg, err := GetHelmActionConfig(namespace)
cfg, err := GetHelmActionConfig(ctx, namespace, deployment.AgentDeployment)
if err != nil {
return nil, err
}
Expand All @@ -138,13 +149,17 @@ func RunHelmUpgrade(
}
}

func GetHelmManifest(namespace, releaseName string) ([]*unstructured.Unstructured, error) {
cfg, err := GetHelmActionConfig(namespace)
func GetHelmManifest(
ctx context.Context,
namespace string,
deployment api.KubernetesAgentDeployment,
) ([]*unstructured.Unstructured, error) {
cfg, err := GetHelmActionConfig(ctx, namespace, deployment.AgentDeployment)
if err != nil {
return nil, err
}
getAction := action.NewGet(cfg)
if release, err := getAction.Run(releaseName); err != nil {
if release, err := getAction.Run(deployment.ReleaseName); err != nil {
return nil, err
} else {
// decode the release manifests which is represented as multi-document YAML
Expand Down
5 changes: 3 additions & 2 deletions cmd/agent/kubernetes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,13 @@ func main() {
}
}

latestRelease, err := GetLatestHelmRelease(res.Namespace, res.Deployment.ReleaseName)
latestRelease, err := GetLatestHelmRelease(ctx, res.Namespace, *res.Deployment)
if err != nil {
if errors.Is(err, driver.ErrReleaseNotFound) {
logger.Info("current helm release does not exist")
} else {
logger.Error("could not get latest helm revision", zap.Error(err))
pushErrorStatus(ctx, err)
continue
}
} else if currentDeployment != nil {
Expand Down Expand Up @@ -164,7 +165,7 @@ func main() {
}
} else {
logger.Info("no action required. running status check")
if resources, err := GetHelmManifest(res.Namespace, res.Deployment.ReleaseName); err != nil {
if resources, err := GetHelmManifest(ctx, res.Namespace, *res.Deployment); err != nil {
logger.Warn("could not get helm manifest", zap.Error(err))
pushErrorStatus(ctx, fmt.Errorf("could not get helm manifest: %w", err))
} else {
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/aws/aws-sdk-go-v2 v1.36.1
github.com/aws/aws-sdk-go-v2/config v1.29.6
github.com/aws/aws-sdk-go-v2/service/ses v1.29.10
github.com/docker/cli v27.1.0+incompatible
github.com/getsentry/sentry-go v0.31.1
github.com/go-chi/chi/v5 v5.2.1
github.com/go-chi/httprate v0.14.1
Expand All @@ -27,6 +28,7 @@ require (
k8s.io/apimachinery v0.32.2
k8s.io/cli-runtime v0.32.2
k8s.io/client-go v0.32.2
oras.land/oras-go v1.2.6
)

require (
Expand Down Expand Up @@ -63,7 +65,6 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/cli v25.0.1+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v27.2.0+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
Expand Down Expand Up @@ -91,7 +92,7 @@ require (
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
Expand All @@ -105,7 +106,7 @@ require (
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
Expand Down Expand Up @@ -176,7 +177,6 @@ require (
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/kubectl v0.32.1 // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
oras.land/oras-go v1.2.5 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/kustomize/api v0.18.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect
Expand Down
Loading

0 comments on commit c9ddc78

Please sign in to comment.