Skip to content

Commit

Permalink
feat: add "connect" support for the kubernetes agent (#254)
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 Jan 13, 2025
1 parent 4a8cf2f commit 6fe5cee
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Dockerfile.kubernetes-agent
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} \
FROM gcr.io/distroless/static-debian12:nonroot@sha256:5c7e2b465ac6a2a4e5f4f7f722ce43b147dabe87cb21ac6c4007ae5178a1fa58
WORKDIR /
COPY --from=builder /workspace/agent .

USER 65532:65532
ENTRYPOINT ["/agent"]
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class ConnectInstructionsComponent {
this.modalConnectCommand =
this.deploymentTarget.type === 'docker'
? `curl "${response.connectUrl}" | docker compose -f - up -d`
: `kubectl apply -f "${response.connectUrl}`;
: `kubectl apply -n ${this.deploymentTarget.namespace} -f "${response.connectUrl}"`;
this.modalTargetId = response.targetId;
this.modalTargetSecret = response.targetSecret;
});
Expand Down
31 changes: 18 additions & 13 deletions internal/handlers/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,35 +51,40 @@ func AgentRouter(r chi.Router) {
}

func connectHandler() http.HandlerFunc {
tmpl := util.Require(resources.GetTemplate("embedded/agent-base.yaml"))
dockerTempl := util.Require(resources.GetTemplate("embedded/agent/docker/docker-compose.yaml"))
kubernetesTempl := util.Require(resources.GetTemplate("embedded/agent/kubernetes/manifest.yaml"))
loginEndpoint, resourcesEndpoint, statusEndpoint, err := buildEndpoints()
util.Must(err)

return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log := internalctx.GetLogger(ctx)
deploymentTarget := internalctx.GetDeploymentTarget(ctx)
templateData := map[string]any{
"loginEndpoint": loginEndpoint,
"resourcesEndpoint": resourcesEndpoint,
"statusEndpoint": statusEndpoint,
"targetId": r.URL.Query().Get("targetId"),
"targetSecret": r.URL.Query().Get("targetSecret"),
"agentInterval": env.AgentInterval(),
}
if deploymentTarget.CurrentStatus != nil {
log.Warn("deployment target has already been connected")
w.WriteHeader(http.StatusBadRequest)
http.Error(w, "deployment target has already been connected", http.StatusBadRequest)
} else if deploymentTarget.Type == types.DeploymentTypeDocker {
w.Header().Add("Content-Type", "application/yaml")
if err := tmpl.Execute(w, map[string]any{
"loginEndpoint": loginEndpoint,
"resourcesEndpoint": resourcesEndpoint,
"statusEndpoint": statusEndpoint,
"targetId": r.URL.Query().Get("targetId"),
"targetSecret": r.URL.Query().Get("targetSecret"),
"agentInterval": env.AgentInterval(),
}); err != nil {
if err := dockerTempl.Execute(w, templateData); err != nil {
log.Error("failed to execute yaml template", zap.Error(err))
sentry.GetHubFromContext(ctx).CaptureException(err)
w.WriteHeader(http.StatusInternalServerError)
}
} else {
log.Warn("not implemented")
http.Error(w, "not implemented", http.StatusInternalServerError)
// TODO: Implement connect for kubernetes agent
w.Header().Add("Content-Type", "application/yaml")
if err := kubernetesTempl.Execute(w, templateData); err != nil {
log.Error("failed to execute yaml template", zap.Error(err))
sentry.GetHubFromContext(ctx).CaptureException(err)
w.WriteHeader(http.StatusInternalServerError)
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/applications.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ func createSampleApplication(w http.ResponseWriter, r *http.Request) {
}

var composeFileData []byte
if composeFile, err := resources.Get("embedded/shiori-compose.yaml"); err != nil {
if composeFile, err := resources.Get("embedded/apps/shiori/docker-compose.yaml"); err != nil {
log.Warn("failed to read shiori compose file", zap.Error(err))
} else {
composeFileData = composeFile
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
name: glasskube-agent

services:
agent:
network_mode: host
Expand Down
73 changes: 73 additions & 0 deletions internal/resources/embedded/agent/kubernetes/manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
apiVersion: v1
kind: Secret
metadata:
name: glasskube-cloud-agent-env
type: Opaque
stringData:
GK_TARGET_ID: '{{ .targetId }}'
GK_TARGET_SECRET: '{{ .targetSecret }}'
GK_LOGIN_ENDPOINT: '{{ .loginEndpoint }}'
GK_RESOURCE_ENDPOINT: '{{ .resourcesEndpoint }}'
GK_STATUS_ENDPOINT: '{{ .statusEndpoint }}'
GK_INTERVAL: '{{ .agentInterval }}'

---
apiVersion: v1
kind: ServiceAccount
metadata:
name: glasskube-cloud-agent

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: namespace-admin
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: glasskube-cloud-agent
subjects:
- kind: ServiceAccount
name: glasskube-cloud-agent
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: namespace-admin

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: glasskube-cloud-agent
spec:
selector:
matchLabels:
app: glasskube-cloud-agent
template:
metadata:
labels:
app: glasskube-cloud-agent
spec:
serviceAccountName: glasskube-cloud-agent
securityContext:
runAsNonRoot: true
containers:
- name: glasskube-cloud-agent
image: ghcr.io/glasskube/cloud/kubernetes-agent:latest # TODO: use version tag
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: glasskube-cloud-agent-env
resources:
limits:
memory: '128Mi'
cpu: '500m'

0 comments on commit 6fe5cee

Please sign in to comment.