mirror of
https://github.com/GlueOps/autoglue.git
synced 2026-02-13 21:00:06 +01:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cc447c0f5 | ||
|
|
8a0345f7f5 | ||
|
|
bb7114efe9 | ||
|
|
9dd0148764 | ||
|
|
bcc69e1c86 | ||
|
|
a7bf6b43b4 | ||
|
|
ced0a0663f | ||
|
|
dac28d3ea5 | ||
|
|
dd0cefc08a | ||
|
|
842f7c9be6 | ||
|
|
c15311a5a1 | ||
|
|
25ced343c4 | ||
|
|
b72a8d384d | ||
|
|
c786a79b60 | ||
|
|
01b1434842 | ||
|
|
e8c9cde474 | ||
|
|
ae92d05cd4 | ||
|
|
67d50d2b15 | ||
|
|
e5a664b812 | ||
|
|
f722ba8dca | ||
|
|
20e6d8d186 | ||
|
|
85f37cd113 | ||
|
|
fd1a81ecd8 | ||
|
|
793daf3ac3 | ||
|
|
7bef4ef6f1 | ||
|
|
9fa9cd169b | ||
|
|
8812b43346 | ||
|
|
21a6d7d5a1 | ||
|
|
da332c89dd | ||
|
|
fd25825f34 | ||
|
|
de3740e974 | ||
|
|
21dd26503f | ||
|
|
e1da229c30 | ||
|
|
5377e521e9 | ||
|
|
a929561bc8 | ||
|
|
c63f9f1cf3 | ||
|
|
4c02179b70 | ||
|
|
c8289c6936 | ||
|
|
c17caf22a2 | ||
|
|
986eeb9bf9 | ||
|
|
b0bbc13946 | ||
|
|
f50dcae823 | ||
|
|
ab9a77e1f5 | ||
|
|
416b2ff4e2 | ||
|
|
20bef7545c | ||
|
|
15e101439b | ||
|
|
fb0901a812 | ||
|
|
fee4c64551 | ||
|
|
4d37a6363f |
1
Makefile
1
Makefile
@@ -204,6 +204,7 @@ swagger: $(DOCS_JSON) ## Generate Swagger docs if stale
|
|||||||
# --- build ---
|
# --- build ---
|
||||||
build: prepare ui swagger sdk-all ## Build everything: Go hygiene, UI, Swagger, SDKs, then Go binary
|
build: prepare ui swagger sdk-all ## Build everything: Go hygiene, UI, Swagger, SDKs, then Go binary
|
||||||
@echo ">> Building Go binary: $(BIN)"
|
@echo ">> Building Go binary: $(BIN)"
|
||||||
|
@$(GOCMD) get github.com/swaggo/swag/v2@v2.0.0-rc4
|
||||||
@$(GOCMD) build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN) $(MAIN)
|
@$(GOCMD) build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN) $(MAIN)
|
||||||
|
|
||||||
# Handy: print resolved version metadata
|
# Handy: print resolved version metadata
|
||||||
|
|||||||
17
cmd/serve.go
17
cmd/serve.go
@@ -116,6 +116,7 @@ var serveCmd = &cobra.Command{
|
|||||||
log.Printf("failed to enqueue bootstrap_bastion: %v", err)
|
log.Printf("failed to enqueue bootstrap_bastion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
_, err = jobs.Enqueue(
|
_, err = jobs.Enqueue(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
uuid.NewString(),
|
uuid.NewString(),
|
||||||
@@ -156,6 +157,22 @@ var serveCmd = &cobra.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("failed to enqueue cluster bootstrap: %v", err)
|
log.Printf("failed to enqueue cluster bootstrap: %v", err)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
_, err = jobs.Enqueue(
|
||||||
|
context.Background(),
|
||||||
|
uuid.NewString(),
|
||||||
|
"org_key_sweeper",
|
||||||
|
bg.OrgKeySweeperArgs{
|
||||||
|
IntervalS: 3600,
|
||||||
|
RetentionDays: 10,
|
||||||
|
},
|
||||||
|
archer.WithMaxRetries(1),
|
||||||
|
archer.WithScheduleTime(time.Now()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to enqueue org_key_sweeper: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = auth.Refresh(rt.DB, rt.Cfg.JWTPrivateEncKey)
|
_ = auth.Refresh(rt.DB, rt.Cfg.JWTPrivateEncKey)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +1,23 @@
|
|||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
|
dto.ActionResponse:
|
||||||
|
properties:
|
||||||
|
created_at:
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
format: uuid
|
||||||
|
type: string
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
make_target:
|
||||||
|
type: string
|
||||||
|
updated_at:
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
dto.AnnotationResponse:
|
dto.AnnotationResponse:
|
||||||
properties:
|
properties:
|
||||||
created_at:
|
created_at:
|
||||||
@@ -96,10 +114,16 @@ components:
|
|||||||
$ref: '#/components/schemas/dto.RecordSetResponse'
|
$ref: '#/components/schemas/dto.RecordSetResponse'
|
||||||
created_at:
|
created_at:
|
||||||
type: string
|
type: string
|
||||||
|
docker_image:
|
||||||
|
type: string
|
||||||
|
docker_tag:
|
||||||
|
type: string
|
||||||
glueops_load_balancer:
|
glueops_load_balancer:
|
||||||
$ref: '#/components/schemas/dto.LoadBalancerResponse'
|
$ref: '#/components/schemas/dto.LoadBalancerResponse'
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
|
kubeconfig:
|
||||||
|
type: string
|
||||||
last_error:
|
last_error:
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
@@ -109,6 +133,10 @@ components:
|
|||||||
$ref: '#/components/schemas/dto.NodePoolResponse'
|
$ref: '#/components/schemas/dto.NodePoolResponse'
|
||||||
type: array
|
type: array
|
||||||
uniqueItems: false
|
uniqueItems: false
|
||||||
|
org_key:
|
||||||
|
type: string
|
||||||
|
org_secret:
|
||||||
|
type: string
|
||||||
random_token:
|
random_token:
|
||||||
type: string
|
type: string
|
||||||
region:
|
region:
|
||||||
@@ -118,6 +146,42 @@ components:
|
|||||||
updated_at:
|
updated_at:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
dto.ClusterRunResponse:
|
||||||
|
properties:
|
||||||
|
action:
|
||||||
|
type: string
|
||||||
|
cluster_id:
|
||||||
|
format: uuid
|
||||||
|
type: string
|
||||||
|
created_at:
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
finished_at:
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
format: uuid
|
||||||
|
type: string
|
||||||
|
organization_id:
|
||||||
|
format: uuid
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
updated_at:
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
dto.CreateActionRequest:
|
||||||
|
properties:
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
make_target:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
dto.CreateAnnotationRequest:
|
dto.CreateAnnotationRequest:
|
||||||
properties:
|
properties:
|
||||||
key:
|
key:
|
||||||
@@ -129,6 +193,10 @@ components:
|
|||||||
properties:
|
properties:
|
||||||
cluster_provider:
|
cluster_provider:
|
||||||
type: string
|
type: string
|
||||||
|
docker_image:
|
||||||
|
type: string
|
||||||
|
docker_tag:
|
||||||
|
type: string
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
region:
|
region:
|
||||||
@@ -702,6 +770,15 @@ components:
|
|||||||
example: Bearer
|
example: Bearer
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
dto.UpdateActionRequest:
|
||||||
|
properties:
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
make_target:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
dto.UpdateAnnotationRequest:
|
dto.UpdateAnnotationRequest:
|
||||||
properties:
|
properties:
|
||||||
key:
|
key:
|
||||||
@@ -713,6 +790,10 @@ components:
|
|||||||
properties:
|
properties:
|
||||||
cluster_provider:
|
cluster_provider:
|
||||||
type: string
|
type: string
|
||||||
|
docker_image:
|
||||||
|
type: string
|
||||||
|
docker_tag:
|
||||||
|
type: string
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
region:
|
region:
|
||||||
@@ -1025,6 +1106,8 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
models.APIKey:
|
models.APIKey:
|
||||||
properties:
|
properties:
|
||||||
|
cluster_id:
|
||||||
|
type: string
|
||||||
created_at:
|
created_at:
|
||||||
format: date-time
|
format: date-time
|
||||||
type: string
|
type: string
|
||||||
@@ -1034,6 +1117,8 @@ components:
|
|||||||
id:
|
id:
|
||||||
format: uuid
|
format: uuid
|
||||||
type: string
|
type: string
|
||||||
|
is_ephemeral:
|
||||||
|
type: boolean
|
||||||
last_used_at:
|
last_used_at:
|
||||||
format: date-time
|
format: date-time
|
||||||
type: string
|
type: string
|
||||||
@@ -1044,6 +1129,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
prefix:
|
prefix:
|
||||||
type: string
|
type: string
|
||||||
|
purpose:
|
||||||
|
type: string
|
||||||
revoked:
|
revoked:
|
||||||
type: boolean
|
type: boolean
|
||||||
scope:
|
scope:
|
||||||
@@ -1178,6 +1265,222 @@ paths:
|
|||||||
summary: Get JWKS
|
summary: Get JWKS
|
||||||
tags:
|
tags:
|
||||||
- Auth
|
- Auth
|
||||||
|
/admin/actions:
|
||||||
|
get:
|
||||||
|
description: Returns all admin-configured actions.
|
||||||
|
operationId: ListActions
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/dto.ActionResponse'
|
||||||
|
type: array
|
||||||
|
description: OK
|
||||||
|
"401":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Unauthorized
|
||||||
|
"500":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: db error
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: List available actions
|
||||||
|
tags:
|
||||||
|
- Actions
|
||||||
|
post:
|
||||||
|
description: Creates a new admin-configured action.
|
||||||
|
operationId: CreateAction
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/dto.CreateActionRequest'
|
||||||
|
description: payload
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/dto.ActionResponse'
|
||||||
|
description: Created
|
||||||
|
"400":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: bad request
|
||||||
|
"401":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Unauthorized
|
||||||
|
"500":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: db error
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Create an action
|
||||||
|
tags:
|
||||||
|
- Actions
|
||||||
|
/admin/actions/{actionID}:
|
||||||
|
delete:
|
||||||
|
description: Deletes an action.
|
||||||
|
operationId: DeleteAction
|
||||||
|
parameters:
|
||||||
|
- description: Action ID
|
||||||
|
in: path
|
||||||
|
name: actionID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: deleted
|
||||||
|
"400":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: bad request
|
||||||
|
"401":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Unauthorized
|
||||||
|
"404":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: not found
|
||||||
|
"500":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: db error
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Delete an action
|
||||||
|
tags:
|
||||||
|
- Actions
|
||||||
|
get:
|
||||||
|
description: Returns a single action.
|
||||||
|
operationId: GetAction
|
||||||
|
parameters:
|
||||||
|
- description: Action ID
|
||||||
|
in: path
|
||||||
|
name: actionID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/dto.ActionResponse'
|
||||||
|
description: OK
|
||||||
|
"400":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: bad request
|
||||||
|
"401":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Unauthorized
|
||||||
|
"404":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: not found
|
||||||
|
"500":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: db error
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Get a single action by ID
|
||||||
|
tags:
|
||||||
|
- Actions
|
||||||
|
patch:
|
||||||
|
description: Updates an action. Only provided fields are modified.
|
||||||
|
operationId: UpdateAction
|
||||||
|
parameters:
|
||||||
|
- description: Action ID
|
||||||
|
in: path
|
||||||
|
name: actionID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/dto.UpdateActionRequest'
|
||||||
|
description: payload
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/dto.ActionResponse'
|
||||||
|
description: OK
|
||||||
|
"400":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: bad request
|
||||||
|
"401":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Unauthorized
|
||||||
|
"404":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: not found
|
||||||
|
"500":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: db error
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Update an action
|
||||||
|
tags:
|
||||||
|
- Actions
|
||||||
/admin/archer/jobs:
|
/admin/archer/jobs:
|
||||||
get:
|
get:
|
||||||
description: Paginated background jobs with optional filters. Search `q` may
|
description: Paginated background jobs with optional filters. Search `q` may
|
||||||
@@ -2100,6 +2403,73 @@ paths:
|
|||||||
summary: Update basic cluster details (org scoped)
|
summary: Update basic cluster details (org scoped)
|
||||||
tags:
|
tags:
|
||||||
- Clusters
|
- Clusters
|
||||||
|
/clusters/{clusterID}/actions/{actionID}/runs:
|
||||||
|
post:
|
||||||
|
description: Creates a ClusterRun record for the cluster/action. Execution is
|
||||||
|
handled asynchronously by workers.
|
||||||
|
operationId: RunClusterAction
|
||||||
|
parameters:
|
||||||
|
- description: Organization UUID
|
||||||
|
in: header
|
||||||
|
name: X-Org-ID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: Cluster ID
|
||||||
|
in: path
|
||||||
|
name: clusterID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: Action ID
|
||||||
|
in: path
|
||||||
|
name: actionID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/dto.ClusterRunResponse'
|
||||||
|
description: Created
|
||||||
|
"400":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: bad request
|
||||||
|
"401":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Unauthorized
|
||||||
|
"403":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: organization required
|
||||||
|
"404":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: cluster or action not found
|
||||||
|
"500":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: db error
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
- OrgKeyAuth: []
|
||||||
|
- OrgSecretAuth: []
|
||||||
|
summary: Run an admin-configured action on a cluster (org scoped)
|
||||||
|
tags:
|
||||||
|
- ClusterRuns
|
||||||
/clusters/{clusterID}/apps-load-balancer:
|
/clusters/{clusterID}/apps-load-balancer:
|
||||||
delete:
|
delete:
|
||||||
description: Clears apps_load_balancer_id on the cluster.
|
description: Clears apps_load_balancer_id on the cluster.
|
||||||
@@ -2993,6 +3363,128 @@ paths:
|
|||||||
summary: Detach a node pool from a cluster
|
summary: Detach a node pool from a cluster
|
||||||
tags:
|
tags:
|
||||||
- Clusters
|
- Clusters
|
||||||
|
/clusters/{clusterID}/runs:
|
||||||
|
get:
|
||||||
|
description: Returns runs for a cluster within the organization in X-Org-ID.
|
||||||
|
operationId: ListClusterRuns
|
||||||
|
parameters:
|
||||||
|
- description: Organization UUID
|
||||||
|
in: header
|
||||||
|
name: X-Org-ID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: Cluster ID
|
||||||
|
in: path
|
||||||
|
name: clusterID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/dto.ClusterRunResponse'
|
||||||
|
type: array
|
||||||
|
description: OK
|
||||||
|
"401":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Unauthorized
|
||||||
|
"403":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: organization required
|
||||||
|
"404":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: cluster not found
|
||||||
|
"500":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: db error
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
- OrgKeyAuth: []
|
||||||
|
- OrgSecretAuth: []
|
||||||
|
summary: List cluster runs (org scoped)
|
||||||
|
tags:
|
||||||
|
- ClusterRuns
|
||||||
|
/clusters/{clusterID}/runs/{runID}:
|
||||||
|
get:
|
||||||
|
description: Returns a single run for a cluster within the organization in X-Org-ID.
|
||||||
|
operationId: GetClusterRun
|
||||||
|
parameters:
|
||||||
|
- description: Organization UUID
|
||||||
|
in: header
|
||||||
|
name: X-Org-ID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: Cluster ID
|
||||||
|
in: path
|
||||||
|
name: clusterID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: Run ID
|
||||||
|
in: path
|
||||||
|
name: runID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/dto.ClusterRunResponse'
|
||||||
|
description: OK
|
||||||
|
"400":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: bad request
|
||||||
|
"401":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Unauthorized
|
||||||
|
"403":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: organization required
|
||||||
|
"404":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: not found
|
||||||
|
"500":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: db error
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
- OrgKeyAuth: []
|
||||||
|
- OrgSecretAuth: []
|
||||||
|
summary: Get a cluster run (org scoped)
|
||||||
|
tags:
|
||||||
|
- ClusterRuns
|
||||||
/credentials:
|
/credentials:
|
||||||
get:
|
get:
|
||||||
description: Returns credential metadata for the current org. Secrets are never
|
description: Returns credential metadata for the current org. Secrets are never
|
||||||
|
|||||||
48
go.mod
48
go.mod
@@ -4,11 +4,11 @@ go 1.25.4
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexedwards/argon2id v1.0.0
|
github.com/alexedwards/argon2id v1.0.0
|
||||||
github.com/aws/aws-sdk-go-v2 v1.40.1
|
github.com/aws/aws-sdk-go-v2 v1.41.0
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.32.3
|
github.com/aws/aws-sdk-go-v2/config v1.32.6
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.3
|
github.com/aws/aws-sdk-go-v2/credentials v1.19.6
|
||||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.61.1
|
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.0
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.94.0
|
||||||
github.com/coreos/go-oidc/v3 v3.17.0
|
github.com/coreos/go-oidc/v3 v3.17.0
|
||||||
github.com/dyaksa/archer v1.1.5
|
github.com/dyaksa/archer v1.1.5
|
||||||
github.com/fergusstrange/embedded-postgres v1.33.0
|
github.com/fergusstrange/embedded-postgres v1.33.0
|
||||||
@@ -16,7 +16,7 @@ require (
|
|||||||
github.com/go-chi/chi/v5 v5.2.3
|
github.com/go-chi/chi/v5 v5.2.3
|
||||||
github.com/go-chi/cors v1.2.2
|
github.com/go-chi/cors v1.2.2
|
||||||
github.com/go-chi/httprate v0.15.0
|
github.com/go-chi/httprate v0.15.0
|
||||||
github.com/go-playground/validator/v10 v10.28.0
|
github.com/go-playground/validator/v10 v10.30.1
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
@@ -25,7 +25,7 @@ require (
|
|||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/spf13/viper v1.21.0
|
github.com/spf13/viper v1.21.0
|
||||||
github.com/swaggo/swag/v2 v2.0.0-rc4
|
github.com/swaggo/swag/v2 v2.0.0-rc4
|
||||||
golang.org/x/crypto v0.45.0
|
golang.org/x/crypto v0.46.0
|
||||||
golang.org/x/oauth2 v0.34.0
|
golang.org/x/oauth2 v0.34.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/datatypes v1.2.7
|
gorm.io/datatypes v1.2.7
|
||||||
@@ -39,19 +39,19 @@ require (
|
|||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 // indirect
|
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 // indirect
|
||||||
github.com/aws/smithy-go v1.24.0 // indirect
|
github.com/aws/smithy-go v1.24.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bytedance/sonic v1.14.0 // indirect
|
github.com/bytedance/sonic v1.14.0 // indirect
|
||||||
@@ -61,7 +61,7 @@ require (
|
|||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a // indirect
|
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a // indirect
|
||||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
|
||||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||||
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||||
@@ -122,12 +122,12 @@ require (
|
|||||||
go.uber.org/mock v0.5.0 // indirect
|
go.uber.org/mock v0.5.0 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/arch v0.20.0 // indirect
|
golang.org/x/arch v0.20.0 // indirect
|
||||||
golang.org/x/mod v0.29.0 // indirect
|
golang.org/x/mod v0.30.0 // indirect
|
||||||
golang.org/x/net v0.47.0 // indirect
|
golang.org/x/net v0.47.0 // indirect
|
||||||
golang.org/x/sync v0.18.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/sys v0.38.0 // indirect
|
golang.org/x/sys v0.39.0 // indirect
|
||||||
golang.org/x/text v0.31.0 // indirect
|
golang.org/x/text v0.32.0 // indirect
|
||||||
golang.org/x/tools v0.38.0 // indirect
|
golang.org/x/tools v0.39.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.9 // indirect
|
google.golang.org/protobuf v1.36.9 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gorm.io/driver/mysql v1.5.7 // indirect
|
gorm.io/driver/mysql v1.5.7 // indirect
|
||||||
|
|||||||
110
go.sum
110
go.sum
@@ -10,44 +10,52 @@ github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 h1:VauE2GcJNZFun2O
|
|||||||
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o=
|
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o=
|
||||||
github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHcQQP0w=
|
github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHcQQP0w=
|
||||||
github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw=
|
github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.40.1 h1:difXb4maDZkRH0x//Qkwcfpdg1XQVXEAEs2DdXldFFc=
|
github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.40.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
|
github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.32.3 h1:cpz7H2uMNTDa0h/5CYL5dLUEzPSLo2g0NkbxTRJtSSU=
|
github.com/aws/aws-sdk-go-v2/config v1.32.5 h1:pz3duhAfUgnxbtVhIK39PGF/AHYyrzGEyRD9Og0QrE8=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.32.3/go.mod h1:srtPKaJJe3McW6T/+GMBZyIPc+SeqJsNPJsd4mOYZ6s=
|
github.com/aws/aws-sdk-go-v2/config v1.32.5/go.mod h1:xmDjzSUs/d0BB7ClzYPAZMmgQdrodNjPPhd6bGASwoE=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.3 h1:01Ym72hK43hjwDeJUfi1l2oYLXBAOR8gNSZNmXmvuas=
|
github.com/aws/aws-sdk-go-v2/config v1.32.6 h1:hFLBGUKjmLAekvi1evLi5hVvFQtSo3GYwi+Bx4lpJf8=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.3/go.mod h1:55nWF/Sr9Zvls0bGnWkRxUdhzKqj9uRNlPvgV1vgxKc=
|
github.com/aws/aws-sdk-go-v2/config v1.32.6/go.mod h1:lcUL/gcd8WyjCrMnxez5OXkO3/rwcNmvfno62tnXNcI=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15 h1:utxLraaifrSBkeyII9mIbVwXXWrZdlPO7FIKmyLCEcY=
|
github.com/aws/aws-sdk-go-v2/credentials v1.19.5 h1:xMo63RlqP3ZZydpJDMBsH9uJ10hgHYfQFIk1cHDXrR4=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15/go.mod h1:hW6zjYUDQwfz3icf4g2O41PHi77u10oAzJ84iSzR/lo=
|
github.com/aws/aws-sdk-go-v2/credentials v1.19.5/go.mod h1:hhbH6oRcou+LpXfA/0vPElh/e0M3aFeOblE1sssAAEk=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15 h1:Y5YXgygXwDI5P4RkteB5yF7v35neH7LfJKBG+hzIons=
|
github.com/aws/aws-sdk-go-v2/credentials v1.19.6 h1:F9vWao2TwjV2MyiyVS+duza0NIRtAslgLUM0vTA1ZaE=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15/go.mod h1:K+/1EpG42dFSY7CBj+Fruzm8PsCGWTXJ3jdeJ659oGQ=
|
github.com/aws/aws-sdk-go-v2/credentials v1.19.6/go.mod h1:SgHzKjEVsdQr6Opor0ihgWtkWdfRAIwxYzSJ8O85VHY=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15 h1:AvltKnW9ewxX2hFmQS0FyJH93aSvJVUEFvXfU+HWtSE=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 h1:80+uETIWS1BqjnN9uJ0dBUaETh+P1XwFy5vwHwK5r9k=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15/go.mod h1:3I4oCdZdmgrREhU74qS1dK9yZ62yumob+58AbFR4cQA=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16/go.mod h1:wOOsYuxYuB/7FlnVtzeBYRcjSRtQpAW0hCP7tIULMwo=
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc=
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA=
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U=
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15 h1:NLYTEyZmVZo0Qh183sC8nC+ydJXOOeIL/qI/sS3PdLY=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 h1:CjMzUs78RDDv4ROu3JnJn/Ig1r6ZD7/T2DXLLRpejic=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15/go.mod h1:Z803iB3B0bc8oJV8zH2PERLRfQUJ2n2BXISpsA4+O1M=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16/go.mod h1:uVW4OLBqbJXSHJYA9svT9BluSvvwbzLQ2Crf6UPzR3c=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6 h1:P1MU/SuhadGvg2jtviDXPEejU3jBNhoeeAlRadHzvHI=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 h1:DIBqIrJ7hv+e4CmIk2z3pyKT+3B6qVMgRsawHiR3qso=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6/go.mod h1:5KYaMG6wmVKMFBSfWoyG/zH8pWwzQFnKgpoSRlXHKdQ=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7/go.mod h1:vLm00xmBke75UmpNvOcZQ/Q30ZFjbczeLFqGx5urmGo=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15 h1:3/u/4yZOffg5jdNk1sDpOQ4Y+R6Xbh+GzpDrSZjuy3U=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15/go.mod h1:4Zkjq0FKjE78NKjabuM4tRXKFzUJWXgP0ItEZK8l7JU=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15 h1:wsSQ4SVz5YE1crz0Ap7VBZrV4nNqZt4CIBBT8mnwoNc=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 h1:NSbvS17MlI2lurYgXnCOLvCFX38sBW4eiVER7+kkgsU=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15/go.mod h1:I7sditnFGtYMIqPRU1QoHZAUrXkGp4SczmlLwrNPlD0=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16/go.mod h1:SwT8Tmqd4sA6G1qaGdzWCJN99bUmPGHfRwwq3G5Qb+A=
|
||||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.61.1 h1:ik9tMw+xWZqzffOtGH3PfV0Yy/V+QsCb1XYXXXjUskk=
|
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.0 h1:80pDB3Tpmb2RCSZORrK9/3iQxsd+w6vSzVqpT1FGiwE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.61.1/go.mod h1:JRqmldxIPU6uck5bcFS8ExwwG2mUwfy+jiUmismOxJs=
|
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.0/go.mod h1:6EZUGGNLPLh5Unt30uEoA+KQcByERfXIkax9qrc80nA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0 h1:IrbE3B8O9pm3lsg96AXIN5MXX4pECEuExh/A0Du3AuI=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.2 h1:U3ygWUhCpiSPYSHOrRhb3gOl9T5Y3kB8k5Vjs//57bE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0/go.mod h1:/sJLzHtiiZvs6C1RbxS/anSAFwZD6oC6M/kotQzOiLw=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.2/go.mod h1:79S2BdqCJpScXZA2y+cpZuocWsjGjJINyXnOsf5DTz8=
|
||||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3 h1:d/6xOGIllc/XW1lzG9a4AUBMmpLA9PXcQnVPTuHHcik=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.94.0 h1:SWTxh/EcUCDVqi/0s26V6pVUq0BBG7kx0tDTmF/hCgA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3/go.mod h1:fQ7E7Qj9GiW8y0ClD7cUJk3Bz5Iw8wZkWDHsTe8vDKs=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.94.0/go.mod h1:79S2BdqCJpScXZA2y+cpZuocWsjGjJINyXnOsf5DTz8=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6 h1:8sTTiw+9yuNXcfWeqKF2x01GqCF49CpP4Z9nKrrk/ts=
|
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 h1:HpI7aMmJ+mm1wkSHIA2t5EaFFv5EFYXePW30p1EIrbQ=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6/go.mod h1:8WYg+Y40Sn3X2hioaaWAAIngndR8n1XFdRPPX+7QBaM=
|
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4/go.mod h1:C5RdGMYGlfM0gYq/tifqgn4EbyX99V15P2V3R+VHbQU=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11 h1:E+KqWoVsSrj1tJ6I/fjDIu5xoS2Zacuu1zT+H7KtiIk=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.30.7 h1:eYnlt6QxnFINKzwxP5/Ucs1vkG7VT3Iezmvfgc2waUw=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11/go.mod h1:qyWHz+4lvkXcr3+PoGlGHEI+3DLLiU6/GdrFfMaAhB0=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.30.7/go.mod h1:+fWt2UHSb4kS7Pu8y+BMBvJF0EWx+4H0hzNwtDNRTrg=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3 h1:tzMkjh0yTChUqJDgGkcDdxvZDSrJ/WB6R6ymI5ehqJI=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 h1:aM/Q24rIlS3bRAhTyFurowU8A0SMyGDtEOY/l/s/1Uw=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3/go.mod h1:T270C0R5sZNLbWUe8ueiAF42XSZxxPocTaGSgs5c/60=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8/go.mod h1:+fWt2UHSb4kS7Pu8y+BMBvJF0EWx+4H0hzNwtDNRTrg=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 h1:AHDr0DaHIAo8c9t1emrzAlVDFp+iMMKnPdYy6XO4MCE=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12/go.mod h1:GQ73XawFFiWxyWXMHWfhiomvP3tXtdNar/fi8z18sx0=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk=
|
||||||
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
||||||
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
@@ -81,6 +89,10 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S
|
|||||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=
|
github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||||
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
||||||
@@ -114,6 +126,10 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
|||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
|
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
|
||||||
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
|
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
|
||||||
|
github.com/go-playground/validator/v10 v10.29.0 h1:lQlF5VNJWNlRbRZNeOIkWElR+1LL/OuHcc0Kp14w1xk=
|
||||||
|
github.com/go-playground/validator/v10 v10.29.0/go.mod h1:D6QxqeMlgIPuT02L66f2ccrZ7AGgHkzKmmTMZhk/Kc4=
|
||||||
|
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
|
||||||
|
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
@@ -290,12 +306,12 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
@@ -304,15 +320,13 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||||
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
|
|
||||||
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
|
||||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -328,29 +342,29 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||||
|
|||||||
@@ -22,5 +22,16 @@ func mountAdminRoutes(r chi.Router, db *gorm.DB, jobs *bg.Jobs, authUser func(ht
|
|||||||
archer.Post("/jobs/{id}/cancel", handlers.AdminCancelArcherJob(db))
|
archer.Post("/jobs/{id}/cancel", handlers.AdminCancelArcherJob(db))
|
||||||
archer.Get("/queues", handlers.AdminListArcherQueues(db))
|
archer.Get("/queues", handlers.AdminListArcherQueues(db))
|
||||||
})
|
})
|
||||||
|
admin.Route("/actions", func(action chi.Router) {
|
||||||
|
action.Use(authUser)
|
||||||
|
action.Use(httpmiddleware.RequirePlatformAdmin())
|
||||||
|
|
||||||
|
action.Get("/", handlers.ListActions(db))
|
||||||
|
action.Post("/", handlers.CreateAction(db))
|
||||||
|
|
||||||
|
action.Get("/{actionID}", handlers.GetAction(db))
|
||||||
|
action.Patch("/{actionID}", handlers.UpdateAction(db))
|
||||||
|
action.Delete("/{actionID}", handlers.DeleteAction(db))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func mountAPIRoutes(r chi.Router, db *gorm.DB, jobs *bg.Jobs) {
|
|||||||
mountNodePoolRoutes(v1, db, authOrg)
|
mountNodePoolRoutes(v1, db, authOrg)
|
||||||
mountDNSRoutes(v1, db, authOrg)
|
mountDNSRoutes(v1, db, authOrg)
|
||||||
mountLoadBalancerRoutes(v1, db, authOrg)
|
mountLoadBalancerRoutes(v1, db, authOrg)
|
||||||
mountClusterRoutes(v1, db, authOrg)
|
mountClusterRoutes(v1, db, jobs, authOrg)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ package api
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/glueops/autoglue/internal/bg"
|
||||||
"github.com/glueops/autoglue/internal/handlers"
|
"github.com/glueops/autoglue/internal/handlers"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mountClusterRoutes(r chi.Router, db *gorm.DB, authOrg func(http.Handler) http.Handler) {
|
func mountClusterRoutes(r chi.Router, db *gorm.DB, jobs *bg.Jobs, authOrg func(http.Handler) http.Handler) {
|
||||||
r.Route("/clusters", func(c chi.Router) {
|
r.Route("/clusters", func(c chi.Router) {
|
||||||
c.Use(authOrg)
|
c.Use(authOrg)
|
||||||
c.Get("/", handlers.ListClusters(db))
|
c.Get("/", handlers.ListClusters(db))
|
||||||
@@ -36,6 +37,10 @@ func mountClusterRoutes(r chi.Router, db *gorm.DB, authOrg func(http.Handler) ht
|
|||||||
c.Delete("/{clusterID}/kubeconfig", handlers.ClearClusterKubeconfig(db))
|
c.Delete("/{clusterID}/kubeconfig", handlers.ClearClusterKubeconfig(db))
|
||||||
|
|
||||||
c.Post("/{clusterID}/node-pools", handlers.AttachNodePool(db))
|
c.Post("/{clusterID}/node-pools", handlers.AttachNodePool(db))
|
||||||
c.Delete("/{clusterID}/node-pools/{nodePoolID}", handlers.DeleteNodePool(db))
|
c.Delete("/{clusterID}/node-pools/{nodePoolID}", handlers.DetachNodePool(db))
|
||||||
|
|
||||||
|
c.Get("/{clusterID}/runs", handlers.ListClusterRuns(db))
|
||||||
|
c.Get("/{clusterID}/runs/{runID}", handlers.GetClusterRun(db))
|
||||||
|
c.Post("/{clusterID}/actions/{actionID}/runs", handlers.RunClusterAction(db, jobs))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ func NewRuntime() *Runtime {
|
|||||||
&models.RecordSet{},
|
&models.RecordSet{},
|
||||||
&models.LoadBalancer{},
|
&models.LoadBalancer{},
|
||||||
&models.Cluster{},
|
&models.Cluster{},
|
||||||
|
&models.Action{},
|
||||||
|
&models.Cluster{},
|
||||||
|
&models.ClusterRun{},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func NewJobs(gdb *gorm.DB, dbUrl string) (*Jobs, error) {
|
|||||||
archer.WithInstances(1),
|
archer.WithInstances(1),
|
||||||
archer.WithTimeout(2*time.Minute),
|
archer.WithTimeout(2*time.Minute),
|
||||||
)
|
)
|
||||||
|
/*
|
||||||
c.Register(
|
c.Register(
|
||||||
"prepare_cluster",
|
"prepare_cluster",
|
||||||
ClusterPrepareWorker(gdb, jobs),
|
ClusterPrepareWorker(gdb, jobs),
|
||||||
@@ -129,6 +129,16 @@ func NewJobs(gdb *gorm.DB, dbUrl string) (*Jobs, error) {
|
|||||||
archer.WithTimeout(60*time.Minute),
|
archer.WithTimeout(60*time.Minute),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
c.Register(
|
||||||
|
"org_key_sweeper",
|
||||||
|
OrgKeySweeperWorker(gdb, jobs),
|
||||||
|
archer.WithInstances(1),
|
||||||
|
archer.WithTimeout(5*time.Minute),
|
||||||
|
)
|
||||||
|
|
||||||
|
c.Register("cluster_action", ClusterActionWorker(gdb))
|
||||||
return jobs, nil
|
return jobs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
166
internal/bg/cluster_action.go
Normal file
166
internal/bg/cluster_action.go
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
package bg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dyaksa/archer"
|
||||||
|
"github.com/dyaksa/archer/job"
|
||||||
|
"github.com/glueops/autoglue/internal/mapper"
|
||||||
|
"github.com/glueops/autoglue/internal/models"
|
||||||
|
"github.com/glueops/autoglue/internal/utils"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClusterActionArgs struct {
|
||||||
|
OrgID uuid.UUID `json:"org_id"`
|
||||||
|
ClusterID uuid.UUID `json:"cluster_id"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
MakeTarget string `json:"make_target"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClusterActionResult struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
ClusterID string `json:"cluster_id"`
|
||||||
|
ElapsedMs int `json:"elapsed_ms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClusterActionWorker(db *gorm.DB) archer.WorkerFn {
|
||||||
|
return func(ctx context.Context, j job.Job) (any, error) {
|
||||||
|
start := time.Now()
|
||||||
|
var args ClusterActionArgs
|
||||||
|
_ = j.ParseArguments(&args)
|
||||||
|
|
||||||
|
logger := log.With().
|
||||||
|
Str("job", j.ID).
|
||||||
|
Str("cluster_id", args.ClusterID.String()).
|
||||||
|
Str("action", args.Action).
|
||||||
|
Logger()
|
||||||
|
|
||||||
|
var c models.Cluster
|
||||||
|
if err := db.
|
||||||
|
Preload("BastionServer.SshKey").
|
||||||
|
Preload("CaptainDomain").
|
||||||
|
Preload("ControlPlaneRecordSet").
|
||||||
|
Preload("AppsLoadBalancer").
|
||||||
|
Preload("GlueOpsLoadBalancer").
|
||||||
|
Preload("NodePools").
|
||||||
|
Preload("NodePools.Labels").
|
||||||
|
Preload("NodePools.Annotations").
|
||||||
|
Preload("NodePools.Taints").
|
||||||
|
Preload("NodePools.Servers.SshKey").
|
||||||
|
Where("id = ? AND organization_id = ?", args.ClusterID, args.OrgID).
|
||||||
|
First(&c).Error; err != nil {
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("load cluster: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Step 1: Prepare (mostly lifted from ClusterPrepareWorker)
|
||||||
|
if err := setClusterStatus(db, c.ID, clusterStatusBootstrapping, ""); err != nil {
|
||||||
|
return nil, fmt.Errorf("mark bootstrapping: %w", err)
|
||||||
|
}
|
||||||
|
c.Status = clusterStatusBootstrapping
|
||||||
|
|
||||||
|
if err := validateClusterForPrepare(&c); err != nil {
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
|
||||||
|
return nil, fmt.Errorf("validate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allServers := flattenClusterServers(&c)
|
||||||
|
keyPayloads, sshConfig, err := buildSSHAssetsForCluster(db, &c, allServers)
|
||||||
|
if err != nil {
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
|
||||||
|
return nil, fmt.Errorf("build ssh assets: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dtoCluster := mapper.ClusterToDTO(c)
|
||||||
|
|
||||||
|
if c.EncryptedKubeconfig != "" && c.KubeIV != "" && c.KubeTag != "" {
|
||||||
|
kubeconfig, err := utils.DecryptForOrg(
|
||||||
|
c.OrganizationID,
|
||||||
|
c.EncryptedKubeconfig,
|
||||||
|
c.KubeIV,
|
||||||
|
c.KubeTag,
|
||||||
|
db,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
|
||||||
|
return nil, fmt.Errorf("decrypt kubeconfig: %w", err)
|
||||||
|
}
|
||||||
|
dtoCluster.Kubeconfig = &kubeconfig
|
||||||
|
}
|
||||||
|
|
||||||
|
orgKey, orgSecret, err := findOrCreateClusterAutomationKey(db, c.OrganizationID, c.ID, 24*time.Hour)
|
||||||
|
if err != nil {
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
|
||||||
|
return nil, fmt.Errorf("org key: %w", err)
|
||||||
|
}
|
||||||
|
dtoCluster.OrgKey = &orgKey
|
||||||
|
dtoCluster.OrgSecret = &orgSecret
|
||||||
|
|
||||||
|
payloadJSON, err := json.MarshalIndent(dtoCluster, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
|
||||||
|
return nil, fmt.Errorf("marshal payload: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
runCtx, cancel := context.WithTimeout(ctx, 8*time.Minute)
|
||||||
|
err := pushAssetsToBastion(runCtx, db, &c, sshConfig, keyPayloads, payloadJSON)
|
||||||
|
cancel()
|
||||||
|
if err != nil {
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
|
||||||
|
return nil, fmt.Errorf("push assets: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := setClusterStatus(db, c.ID, clusterStatusPending, ""); err != nil {
|
||||||
|
return nil, fmt.Errorf("mark pending: %w", err)
|
||||||
|
}
|
||||||
|
c.Status = clusterStatusPending
|
||||||
|
|
||||||
|
// ---- Step 2: Setup (ping-servers)
|
||||||
|
{
|
||||||
|
runCtx, cancel := context.WithTimeout(ctx, 30*time.Minute)
|
||||||
|
out, err := runMakeOnBastion(runCtx, db, &c, "ping-servers")
|
||||||
|
cancel()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error().Err(err).Str("output", out).Msg("ping-servers failed")
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make ping-servers: %v", err))
|
||||||
|
return nil, fmt.Errorf("ping-servers: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := setClusterStatus(db, c.ID, clusterStatusProvisioning, ""); err != nil {
|
||||||
|
return nil, fmt.Errorf("mark provisioning: %w", err)
|
||||||
|
}
|
||||||
|
c.Status = clusterStatusProvisioning
|
||||||
|
|
||||||
|
// ---- Step 3: Bootstrap (parameterized target)
|
||||||
|
{
|
||||||
|
runCtx, cancel := context.WithTimeout(ctx, 60*time.Minute)
|
||||||
|
out, err := runMakeOnBastion(runCtx, db, &c, args.MakeTarget)
|
||||||
|
cancel()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error().Err(err).Str("output", out).Msg("bootstrap target failed")
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make %s: %v", args.MakeTarget, err))
|
||||||
|
return nil, fmt.Errorf("make %s: %w", args.MakeTarget, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := setClusterStatus(db, c.ID, clusterStatusReady, ""); err != nil {
|
||||||
|
return nil, fmt.Errorf("mark ready: %w", err)
|
||||||
|
}
|
||||||
|
return ClusterActionResult{
|
||||||
|
Status: "ok",
|
||||||
|
Action: args.Action,
|
||||||
|
ClusterID: c.ID.String(),
|
||||||
|
ElapsedMs: int(time.Since(start).Milliseconds()),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -68,14 +68,14 @@ func ClusterBootstrapWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
|
|||||||
logger.Info().Msg("[cluster_bootstrap] running make bootstrap")
|
logger.Info().Msg("[cluster_bootstrap] running make bootstrap")
|
||||||
|
|
||||||
runCtx, cancel := context.WithTimeout(ctx, perClusterTimeout)
|
runCtx, cancel := context.WithTimeout(ctx, perClusterTimeout)
|
||||||
out, err := runMakeOnBastion(runCtx, db, c, "bootstrap")
|
out, err := runMakeOnBastion(runCtx, db, c, "setup")
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failCount++
|
failCount++
|
||||||
failedIDs = append(failedIDs, c.ID)
|
failedIDs = append(failedIDs, c.ID)
|
||||||
logger.Error().Err(err).Str("output", out).Msg("[cluster_bootstrap] make bootstrap failed")
|
logger.Error().Err(err).Str("output", out).Msg("[cluster_bootstrap] make setup failed")
|
||||||
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make bootstrap: %v", err))
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make setup: %v", err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,14 +68,14 @@ func ClusterSetupWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
|
|||||||
logger.Info().Msg("[cluster_setup] running make setup")
|
logger.Info().Msg("[cluster_setup] running make setup")
|
||||||
|
|
||||||
runCtx, cancel := context.WithTimeout(ctx, perClusterTimeout)
|
runCtx, cancel := context.WithTimeout(ctx, perClusterTimeout)
|
||||||
out, err := runMakeOnBastion(runCtx, db, c, "setup")
|
out, err := runMakeOnBastion(runCtx, db, c, "ping-servers")
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failCount++
|
failCount++
|
||||||
failedIDs = append(failedIDs, c.ID)
|
failedIDs = append(failedIDs, c.ID)
|
||||||
logger.Error().Err(err).Str("output", out).Msg("[cluster_setup] make setup failed")
|
logger.Error().Err(err).Str("output", out).Msg("[cluster_setup] make ping-servers failed")
|
||||||
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make setup: %v", err))
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make ping-servers: %v", err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
95
internal/bg/org_key_sweeper.go
Normal file
95
internal/bg/org_key_sweeper.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package bg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dyaksa/archer"
|
||||||
|
"github.com/dyaksa/archer/job"
|
||||||
|
"github.com/glueops/autoglue/internal/models"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrgKeySweeperArgs struct {
|
||||||
|
IntervalS int `json:"interval_seconds,omitempty"`
|
||||||
|
RetentionDays int `json:"retention_days,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrgKeySweeperResult struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
MarkedRevoked int `json:"marked_revoked"`
|
||||||
|
DeletedEphemeral int `json:"deleted_ephemeral"`
|
||||||
|
ElapsedMs int `json:"elapsed_ms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func OrgKeySweeperWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
|
||||||
|
return func(ctx context.Context, j job.Job) (any, error) {
|
||||||
|
args := OrgKeySweeperArgs{
|
||||||
|
IntervalS: 3600,
|
||||||
|
RetentionDays: 10,
|
||||||
|
}
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
_ = j.ParseArguments(&args)
|
||||||
|
if args.IntervalS <= 0 {
|
||||||
|
args.IntervalS = 3600
|
||||||
|
}
|
||||||
|
if args.RetentionDays <= 0 {
|
||||||
|
args.RetentionDays = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
// 1) Mark expired keys as revoked
|
||||||
|
res1 := db.Model(&models.APIKey{}).
|
||||||
|
Where("expires_at IS NOT NULL AND expires_at <= ? AND revoked = false", now).
|
||||||
|
Updates(map[string]any{
|
||||||
|
"revoked": true,
|
||||||
|
"updated_at": now,
|
||||||
|
})
|
||||||
|
|
||||||
|
if res1.Error != nil {
|
||||||
|
log.Error().Err(res1.Error).Msg("[org_key_sweeper] mark expired revoked failed")
|
||||||
|
return nil, res1.Error
|
||||||
|
}
|
||||||
|
markedRevoked := int(res1.RowsAffected)
|
||||||
|
|
||||||
|
// 2) Hard-delete ephemeral keys that are revoked and older than retention
|
||||||
|
cutoff := now.Add(-time.Duration(args.RetentionDays) * 24 * time.Hour)
|
||||||
|
res2 := db.
|
||||||
|
Where("is_ephemeral = ? AND revoked = ? AND updated_at <= ?", true, true, cutoff).
|
||||||
|
Delete(&models.APIKey{})
|
||||||
|
|
||||||
|
if res2.Error != nil {
|
||||||
|
log.Error().Err(res2.Error).Msg("[org_key_sweeper] delete revoked ephemeral keys failed")
|
||||||
|
return nil, res2.Error
|
||||||
|
}
|
||||||
|
deletedEphemeral := int(res2.RowsAffected)
|
||||||
|
|
||||||
|
out := OrgKeySweeperResult{
|
||||||
|
Status: "ok",
|
||||||
|
MarkedRevoked: markedRevoked,
|
||||||
|
DeletedEphemeral: deletedEphemeral,
|
||||||
|
ElapsedMs: int(time.Since(start).Milliseconds()),
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info().
|
||||||
|
Int("marked_revoked", markedRevoked).
|
||||||
|
Int("deleted_ephemeral", deletedEphemeral).
|
||||||
|
Msg("[org_key_sweeper] cleanup tick ok")
|
||||||
|
|
||||||
|
// Re-enqueue the sweeper
|
||||||
|
next := time.Now().Add(time.Duration(args.IntervalS) * time.Second)
|
||||||
|
_, _ = jobs.Enqueue(
|
||||||
|
ctx,
|
||||||
|
uuid.NewString(),
|
||||||
|
"org_key_sweeper",
|
||||||
|
args,
|
||||||
|
archer.WithScheduleTime(next),
|
||||||
|
archer.WithMaxRetries(1),
|
||||||
|
)
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package bg
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -12,6 +13,8 @@ import (
|
|||||||
|
|
||||||
"github.com/dyaksa/archer"
|
"github.com/dyaksa/archer"
|
||||||
"github.com/dyaksa/archer/job"
|
"github.com/dyaksa/archer/job"
|
||||||
|
"github.com/glueops/autoglue/internal/auth"
|
||||||
|
"github.com/glueops/autoglue/internal/mapper"
|
||||||
"github.com/glueops/autoglue/internal/models"
|
"github.com/glueops/autoglue/internal/models"
|
||||||
"github.com/glueops/autoglue/internal/utils"
|
"github.com/glueops/autoglue/internal/utils"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@@ -47,6 +50,7 @@ const (
|
|||||||
clusterStatusProvisioning = models.ClusterStatusProvisioning
|
clusterStatusProvisioning = models.ClusterStatusProvisioning
|
||||||
clusterStatusReady = models.ClusterStatusReady
|
clusterStatusReady = models.ClusterStatusReady
|
||||||
clusterStatusFailed = models.ClusterStatusFailed
|
clusterStatusFailed = models.ClusterStatusFailed
|
||||||
|
clusterStatusBootstrapping = models.ClusterStatusBootstrapping
|
||||||
)
|
)
|
||||||
|
|
||||||
func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
|
func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
|
||||||
@@ -66,6 +70,12 @@ func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
|
|||||||
Preload("BastionServer.SshKey").
|
Preload("BastionServer.SshKey").
|
||||||
Preload("CaptainDomain").
|
Preload("CaptainDomain").
|
||||||
Preload("ControlPlaneRecordSet").
|
Preload("ControlPlaneRecordSet").
|
||||||
|
Preload("AppsLoadBalancer").
|
||||||
|
Preload("GlueOpsLoadBalancer").
|
||||||
|
Preload("NodePools").
|
||||||
|
Preload("NodePools.Labels").
|
||||||
|
Preload("NodePools.Annotations").
|
||||||
|
Preload("NodePools.Taints").
|
||||||
Preload("NodePools.Servers.SshKey").
|
Preload("NodePools.Servers.SshKey").
|
||||||
Where("status = ?", clusterStatusPrePending).
|
Where("status = ?", clusterStatusPrePending).
|
||||||
Find(&clusters).Error; err != nil {
|
Find(&clusters).Error; err != nil {
|
||||||
@@ -88,6 +98,13 @@ func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := setClusterStatus(db, c.ID, clusterStatusBootstrapping, ""); err != nil {
|
||||||
|
log.Error().Err(err).Msg("[cluster_prepare] failed to mark cluster bootstrapping")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Status = clusterStatusBootstrapping
|
||||||
|
|
||||||
clusterLog := log.With().
|
clusterLog := log.With().
|
||||||
Str("job", jobID).
|
Str("job", jobID).
|
||||||
Str("cluster_id", c.ID.String()).
|
Str("cluster_id", c.ID.String()).
|
||||||
@@ -124,7 +141,55 @@ func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadJSON, err := json.MarshalIndent(c, "", " ")
|
dtoCluster := mapper.ClusterToDTO(*c)
|
||||||
|
|
||||||
|
if c.EncryptedKubeconfig != "" && c.KubeIV != "" && c.KubeTag != "" {
|
||||||
|
kubeconfig, err := utils.DecryptForOrg(
|
||||||
|
c.OrganizationID,
|
||||||
|
c.EncryptedKubeconfig,
|
||||||
|
c.KubeIV,
|
||||||
|
c.KubeTag,
|
||||||
|
db,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
fail++
|
||||||
|
failedIDs = append(failedIDs, c.ID)
|
||||||
|
failures = append(failures, ClusterPrepareFailure{
|
||||||
|
ClusterID: c.ID,
|
||||||
|
Step: "decrypt_kubeconfig",
|
||||||
|
Reason: err.Error(),
|
||||||
|
})
|
||||||
|
clusterLog.Error().Err(err).Msg("[cluster_prepare] decrypt kubeconfig failed")
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dtoCluster.Kubeconfig = &kubeconfig
|
||||||
|
}
|
||||||
|
|
||||||
|
orgKey, orgSecret, err := findOrCreateClusterAutomationKey(
|
||||||
|
db,
|
||||||
|
c.OrganizationID,
|
||||||
|
c.ID,
|
||||||
|
24*time.Hour,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fail++
|
||||||
|
failedIDs = append(failedIDs, c.ID)
|
||||||
|
failures = append(failures, ClusterPrepareFailure{
|
||||||
|
ClusterID: c.ID,
|
||||||
|
Step: "create_org_key",
|
||||||
|
Reason: err.Error(),
|
||||||
|
})
|
||||||
|
clusterLog.Error().Err(err).Msg("[cluster_prepare] create org key for payload failed")
|
||||||
|
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dtoCluster.OrgKey = &orgKey
|
||||||
|
dtoCluster.OrgSecret = &orgSecret
|
||||||
|
|
||||||
|
payloadJSON, err := json.MarshalIndent(dtoCluster, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail++
|
fail++
|
||||||
failedIDs = append(failedIDs, c.ID)
|
failedIDs = append(failedIDs, c.ID)
|
||||||
@@ -443,6 +508,11 @@ func runMakeOnBastion(
|
|||||||
c *models.Cluster,
|
c *models.Cluster,
|
||||||
target string,
|
target string,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
|
logger := log.With().
|
||||||
|
Str("cluster_id", c.ID.String()).
|
||||||
|
Str("cluster_name", c.Name).
|
||||||
|
Logger()
|
||||||
|
|
||||||
bastion := c.BastionServer
|
bastion := c.BastionServer
|
||||||
if bastion == nil {
|
if bastion == nil {
|
||||||
return "", fmt.Errorf("bastion server is nil")
|
return "", fmt.Errorf("bastion server is nil")
|
||||||
@@ -500,7 +570,13 @@ func runMakeOnBastion(
|
|||||||
defer sess.Close()
|
defer sess.Close()
|
||||||
|
|
||||||
clusterDir := fmt.Sprintf("$HOME/autoglue/clusters/%s", c.ID.String())
|
clusterDir := fmt.Sprintf("$HOME/autoglue/clusters/%s", c.ID.String())
|
||||||
cmd := fmt.Sprintf("cd %s && make %s", clusterDir, target)
|
sshDir := fmt.Sprintf("$HOME/.ssh")
|
||||||
|
|
||||||
|
cmd := fmt.Sprintf("cd %s && docker run -v %s:/root/.ssh -v ./payload.json:/opt/gluekube/platform.json %s:%s make %s", clusterDir, sshDir, c.DockerImage, c.DockerTag, target)
|
||||||
|
|
||||||
|
logger.Info().
|
||||||
|
Str("cmd", cmd).
|
||||||
|
Msg("[runMakeOnBastion] executing remote command")
|
||||||
|
|
||||||
out, runErr := sess.CombinedOutput(cmd)
|
out, runErr := sess.CombinedOutput(cmd)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
@@ -508,3 +584,75 @@ func runMakeOnBastion(
|
|||||||
}
|
}
|
||||||
return string(out), nil
|
return string(out), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func randomB64URL(n int) (string, error) {
|
||||||
|
b := make([]byte, n)
|
||||||
|
if _, err := rand.Read(b); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return base64.RawURLEncoding.EncodeToString(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func findOrCreateClusterAutomationKey(
|
||||||
|
db *gorm.DB,
|
||||||
|
orgID uuid.UUID,
|
||||||
|
clusterID uuid.UUID,
|
||||||
|
ttl time.Duration,
|
||||||
|
) (orgKey string, orgSecret string, err error) {
|
||||||
|
now := time.Now()
|
||||||
|
name := fmt.Sprintf("cluster-%s-bastion", clusterID.String())
|
||||||
|
|
||||||
|
// 1) Delete any existing ephemeral cluster-bastion key for this org+cluster
|
||||||
|
if err := db.Where(
|
||||||
|
"org_id = ? AND scope = ? AND purpose = ? AND cluster_id = ? AND is_ephemeral = ?",
|
||||||
|
orgID, "org", "cluster_bastion", clusterID, true,
|
||||||
|
).Delete(&models.APIKey{}).Error; err != nil {
|
||||||
|
return "", "", fmt.Errorf("delete existing cluster key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Mint a fresh keypair
|
||||||
|
keySuffix, err := randomB64URL(16)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("entropy_error: %w", err)
|
||||||
|
}
|
||||||
|
sec, err := randomB64URL(32)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("entropy_error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orgKey = "org_" + keySuffix
|
||||||
|
orgSecret = sec
|
||||||
|
|
||||||
|
keyHash := auth.SHA256Hex(orgKey)
|
||||||
|
secretHash, err := auth.HashSecretArgon2id(orgSecret)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("hash_error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
exp := now.Add(ttl)
|
||||||
|
|
||||||
|
prefix := orgKey
|
||||||
|
if len(prefix) > 12 {
|
||||||
|
prefix = prefix[:12]
|
||||||
|
}
|
||||||
|
|
||||||
|
rec := models.APIKey{
|
||||||
|
OrgID: &orgID,
|
||||||
|
Scope: "org",
|
||||||
|
Purpose: "cluster_bastion",
|
||||||
|
ClusterID: &clusterID,
|
||||||
|
IsEphemeral: true,
|
||||||
|
Name: name,
|
||||||
|
KeyHash: keyHash,
|
||||||
|
SecretHash: &secretHash,
|
||||||
|
ExpiresAt: &exp,
|
||||||
|
Revoked: false,
|
||||||
|
Prefix: &prefix,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Create(&rec).Error; err != nil {
|
||||||
|
return "", "", fmt.Errorf("db_error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return orgKey, orgSecret, nil
|
||||||
|
}
|
||||||
|
|||||||
256
internal/handlers/actions.go
Normal file
256
internal/handlers/actions.go
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/glueops/autoglue/internal/handlers/dto"
|
||||||
|
"github.com/glueops/autoglue/internal/models"
|
||||||
|
"github.com/glueops/autoglue/internal/utils"
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListActions godoc
|
||||||
|
//
|
||||||
|
// @ID ListActions
|
||||||
|
// @Summary List available actions
|
||||||
|
// @Description Returns all admin-configured actions.
|
||||||
|
// @Tags Actions
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} dto.ActionResponse
|
||||||
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
|
// @Failure 500 {string} string "db error"
|
||||||
|
// @Router /admin/actions [get]
|
||||||
|
// @Security BearerAuth
|
||||||
|
func ListActions(db *gorm.DB) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var rows []models.Action
|
||||||
|
if err := db.Order("label ASC").Find(&rows).Error; err != nil {
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]dto.ActionResponse, 0, len(rows))
|
||||||
|
for _, a := range rows {
|
||||||
|
out = append(out, actionToDTO(a))
|
||||||
|
}
|
||||||
|
utils.WriteJSON(w, http.StatusOK, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAction godoc
|
||||||
|
//
|
||||||
|
// @ID GetAction
|
||||||
|
// @Summary Get a single action by ID
|
||||||
|
// @Description Returns a single action.
|
||||||
|
// @Tags Actions
|
||||||
|
// @Produce json
|
||||||
|
// @Param actionID path string true "Action ID"
|
||||||
|
// @Success 200 {object} dto.ActionResponse
|
||||||
|
// @Failure 400 {string} string "bad request"
|
||||||
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
|
// @Failure 404 {string} string "not found"
|
||||||
|
// @Failure 500 {string} string "db error"
|
||||||
|
// @Router /admin/actions/{actionID} [get]
|
||||||
|
// @Security BearerAuth
|
||||||
|
func GetAction(db *gorm.DB) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
actionID, err := uuid.Parse(chi.URLParam(r, "actionID"))
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_action_id", "invalid action id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var row models.Action
|
||||||
|
if err := db.Where("id = ?", actionID).First(&row).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
utils.WriteError(w, http.StatusNotFound, "not_found", "action not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteJSON(w, http.StatusOK, actionToDTO(row))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateAction godoc
|
||||||
|
//
|
||||||
|
// @ID CreateAction
|
||||||
|
// @Summary Create an action
|
||||||
|
// @Description Creates a new admin-configured action.
|
||||||
|
// @Tags Actions
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body dto.CreateActionRequest true "payload"
|
||||||
|
// @Success 201 {object} dto.ActionResponse
|
||||||
|
// @Failure 400 {string} string "bad request"
|
||||||
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
|
// @Failure 500 {string} string "db error"
|
||||||
|
// @Router /admin/actions [post]
|
||||||
|
// @Security BearerAuth
|
||||||
|
func CreateAction(db *gorm.DB) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var in dto.CreateActionRequest
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_json", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
label := strings.TrimSpace(in.Label)
|
||||||
|
desc := strings.TrimSpace(in.Description)
|
||||||
|
target := strings.TrimSpace(in.MakeTarget)
|
||||||
|
|
||||||
|
if label == "" {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "validation_error", "label is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if desc == "" {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "validation_error", "description is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if target == "" {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "validation_error", "make_target is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
row := models.Action{
|
||||||
|
Label: label,
|
||||||
|
Description: desc,
|
||||||
|
MakeTarget: target,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Create(&row).Error; err != nil {
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteJSON(w, http.StatusCreated, actionToDTO(row))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAction godoc
|
||||||
|
//
|
||||||
|
// @ID UpdateAction
|
||||||
|
// @Summary Update an action
|
||||||
|
// @Description Updates an action. Only provided fields are modified.
|
||||||
|
// @Tags Actions
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param actionID path string true "Action ID"
|
||||||
|
// @Param body body dto.UpdateActionRequest true "payload"
|
||||||
|
// @Success 200 {object} dto.ActionResponse
|
||||||
|
// @Failure 400 {string} string "bad request"
|
||||||
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
|
// @Failure 404 {string} string "not found"
|
||||||
|
// @Failure 500 {string} string "db error"
|
||||||
|
// @Router /admin/actions/{actionID} [patch]
|
||||||
|
// @Security BearerAuth
|
||||||
|
func UpdateAction(db *gorm.DB) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
actionID, err := uuid.Parse(chi.URLParam(r, "actionID"))
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_action_id", "invalid action id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var in dto.UpdateActionRequest
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_json", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var row models.Action
|
||||||
|
if err := db.Where("id = ?", actionID).First(&row).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
utils.WriteError(w, http.StatusNotFound, "not_found", "action not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.Label != nil {
|
||||||
|
v := strings.TrimSpace(*in.Label)
|
||||||
|
if v == "" {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "validation_error", "label cannot be empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
row.Label = v
|
||||||
|
}
|
||||||
|
if in.Description != nil {
|
||||||
|
v := strings.TrimSpace(*in.Description)
|
||||||
|
if v == "" {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "validation_error", "description cannot be empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
row.Description = v
|
||||||
|
}
|
||||||
|
if in.MakeTarget != nil {
|
||||||
|
v := strings.TrimSpace(*in.MakeTarget)
|
||||||
|
if v == "" {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "validation_error", "make_target cannot be empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
row.MakeTarget = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Save(&row).Error; err != nil {
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.WriteJSON(w, http.StatusOK, actionToDTO(row))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteAction godoc
|
||||||
|
//
|
||||||
|
// @ID DeleteAction
|
||||||
|
// @Summary Delete an action
|
||||||
|
// @Description Deletes an action.
|
||||||
|
// @Tags Actions
|
||||||
|
// @Produce json
|
||||||
|
// @Param actionID path string true "Action ID"
|
||||||
|
// @Success 204 {string} string "deleted"
|
||||||
|
// @Failure 400 {string} string "bad request"
|
||||||
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
|
// @Failure 404 {string} string "not found"
|
||||||
|
// @Failure 500 {string} string "db error"
|
||||||
|
// @Router /admin/actions/{actionID} [delete]
|
||||||
|
// @Security BearerAuth
|
||||||
|
func DeleteAction(db *gorm.DB) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
actionID, err := uuid.Parse(chi.URLParam(r, "actionID"))
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_action_id", "invalid action id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := db.Where("id = ?", actionID).Delete(&models.Action{})
|
||||||
|
if tx.Error != nil {
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if tx.RowsAffected == 0 {
|
||||||
|
utils.WriteError(w, http.StatusNotFound, "not_found", "action not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func actionToDTO(a models.Action) dto.ActionResponse {
|
||||||
|
return dto.ActionResponse{
|
||||||
|
ID: a.ID,
|
||||||
|
Label: a.Label,
|
||||||
|
Description: a.Description,
|
||||||
|
MakeTarget: a.MakeTarget,
|
||||||
|
CreatedAt: a.CreatedAt,
|
||||||
|
UpdatedAt: a.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
257
internal/handlers/cluster_runs.go
Normal file
257
internal/handlers/cluster_runs.go
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dyaksa/archer"
|
||||||
|
"github.com/glueops/autoglue/internal/api/httpmiddleware"
|
||||||
|
"github.com/glueops/autoglue/internal/bg"
|
||||||
|
"github.com/glueops/autoglue/internal/handlers/dto"
|
||||||
|
"github.com/glueops/autoglue/internal/models"
|
||||||
|
"github.com/glueops/autoglue/internal/utils"
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListClusterRuns godoc
|
||||||
|
//
|
||||||
|
// @ID ListClusterRuns
|
||||||
|
// @Summary List cluster runs (org scoped)
|
||||||
|
// @Description Returns runs for a cluster within the organization in X-Org-ID.
|
||||||
|
// @Tags ClusterRuns
|
||||||
|
// @Produce json
|
||||||
|
// @Param X-Org-ID header string false "Organization UUID"
|
||||||
|
// @Param clusterID path string true "Cluster ID"
|
||||||
|
// @Success 200 {array} dto.ClusterRunResponse
|
||||||
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
|
// @Failure 403 {string} string "organization required"
|
||||||
|
// @Failure 404 {string} string "cluster not found"
|
||||||
|
// @Failure 500 {string} string "db error"
|
||||||
|
// @Router /clusters/{clusterID}/runs [get]
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Security OrgKeyAuth
|
||||||
|
// @Security OrgSecretAuth
|
||||||
|
func ListClusterRuns(db *gorm.DB) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
|
||||||
|
if !ok {
|
||||||
|
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterID, err := uuid.Parse(chi.URLParam(r, "clusterID"))
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_cluster_id", "invalid cluster id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure cluster exists + org scoped
|
||||||
|
if err := db.Select("id").
|
||||||
|
Where("id = ? AND organization_id = ?", clusterID, orgID).
|
||||||
|
First(&models.Cluster{}).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
utils.WriteError(w, http.StatusNotFound, "not_found", "cluster not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var rows []models.ClusterRun
|
||||||
|
if err := db.
|
||||||
|
Where("organization_id = ? AND cluster_id = ?", orgID, clusterID).
|
||||||
|
Order("created_at DESC").
|
||||||
|
Find(&rows).Error; err != nil {
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]dto.ClusterRunResponse, 0, len(rows))
|
||||||
|
for _, cr := range rows {
|
||||||
|
out = append(out, clusterRunToDTO(cr))
|
||||||
|
}
|
||||||
|
utils.WriteJSON(w, http.StatusOK, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetClusterRun godoc
|
||||||
|
//
|
||||||
|
// @ID GetClusterRun
|
||||||
|
// @Summary Get a cluster run (org scoped)
|
||||||
|
// @Description Returns a single run for a cluster within the organization in X-Org-ID.
|
||||||
|
// @Tags ClusterRuns
|
||||||
|
// @Produce json
|
||||||
|
// @Param X-Org-ID header string false "Organization UUID"
|
||||||
|
// @Param clusterID path string true "Cluster ID"
|
||||||
|
// @Param runID path string true "Run ID"
|
||||||
|
// @Success 200 {object} dto.ClusterRunResponse
|
||||||
|
// @Failure 400 {string} string "bad request"
|
||||||
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
|
// @Failure 403 {string} string "organization required"
|
||||||
|
// @Failure 404 {string} string "not found"
|
||||||
|
// @Failure 500 {string} string "db error"
|
||||||
|
// @Router /clusters/{clusterID}/runs/{runID} [get]
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Security OrgKeyAuth
|
||||||
|
// @Security OrgSecretAuth
|
||||||
|
func GetClusterRun(db *gorm.DB) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
|
||||||
|
if !ok {
|
||||||
|
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterID, err := uuid.Parse(chi.URLParam(r, "clusterID"))
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_cluster_id", "invalid cluster id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
runID, err := uuid.Parse(chi.URLParam(r, "runID"))
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_run_id", "invalid run id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var row models.ClusterRun
|
||||||
|
if err := db.
|
||||||
|
Where("id = ? AND organization_id = ? AND cluster_id = ?", runID, orgID, clusterID).
|
||||||
|
First(&row).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
utils.WriteError(w, http.StatusNotFound, "not_found", "run not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.WriteJSON(w, http.StatusOK, clusterRunToDTO(row))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunClusterAction godoc
|
||||||
|
//
|
||||||
|
// @ID RunClusterAction
|
||||||
|
// @Summary Run an admin-configured action on a cluster (org scoped)
|
||||||
|
// @Description Creates a ClusterRun record for the cluster/action. Execution is handled asynchronously by workers.
|
||||||
|
// @Tags ClusterRuns
|
||||||
|
// @Produce json
|
||||||
|
// @Param X-Org-ID header string false "Organization UUID"
|
||||||
|
// @Param clusterID path string true "Cluster ID"
|
||||||
|
// @Param actionID path string true "Action ID"
|
||||||
|
// @Success 201 {object} dto.ClusterRunResponse
|
||||||
|
// @Failure 400 {string} string "bad request"
|
||||||
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
|
// @Failure 403 {string} string "organization required"
|
||||||
|
// @Failure 404 {string} string "cluster or action not found"
|
||||||
|
// @Failure 500 {string} string "db error"
|
||||||
|
// @Router /clusters/{clusterID}/actions/{actionID}/runs [post]
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Security OrgKeyAuth
|
||||||
|
// @Security OrgSecretAuth
|
||||||
|
func RunClusterAction(db *gorm.DB, jobs *bg.Jobs) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
|
||||||
|
if !ok {
|
||||||
|
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterID, err := uuid.Parse(chi.URLParam(r, "clusterID"))
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_cluster_id", "invalid cluster id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
actionID, err := uuid.Parse(chi.URLParam(r, "actionID"))
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusBadRequest, "bad_action_id", "invalid action id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// cluster must exist + org scoped
|
||||||
|
var cluster models.Cluster
|
||||||
|
if err := db.Select("id", "organization_id").
|
||||||
|
Where("id = ? AND organization_id = ?", clusterID, orgID).
|
||||||
|
First(&cluster).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
utils.WriteError(w, http.StatusNotFound, "not_found", "cluster not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// action is global/admin-configured (not org scoped)
|
||||||
|
var action models.Action
|
||||||
|
if err := db.Where("id = ?", actionID).First(&action).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
utils.WriteError(w, http.StatusNotFound, "action_not_found", "action not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
run := models.ClusterRun{
|
||||||
|
OrganizationID: orgID,
|
||||||
|
ClusterID: clusterID,
|
||||||
|
Action: action.MakeTarget, // this is what you actually execute
|
||||||
|
Status: models.ClusterRunStatusQueued,
|
||||||
|
Error: "",
|
||||||
|
FinishedAt: time.Time{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Create(&run).Error; err != nil {
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enqueue with run.ID as the job ID so the worker can look it up.
|
||||||
|
_, enqueueErr := jobs.Enqueue(
|
||||||
|
r.Context(),
|
||||||
|
run.ID.String(),
|
||||||
|
"cluster_action",
|
||||||
|
bg.ClusterActionWorker,
|
||||||
|
archer.WithMaxRetries(3),
|
||||||
|
)
|
||||||
|
|
||||||
|
if enqueueErr != nil {
|
||||||
|
_ = db.Model(&models.ClusterRun{}).
|
||||||
|
Where("id = ?", run.ID).
|
||||||
|
Updates(map[string]any{
|
||||||
|
"status": models.ClusterRunStatusFailed,
|
||||||
|
"error": "failed to enqueue job",
|
||||||
|
"finished_at": time.Now().UTC(),
|
||||||
|
}).Error
|
||||||
|
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "job_error", "failed to enqueue cluster action")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteJSON(w, http.StatusCreated, clusterRunToDTO(run))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func clusterRunToDTO(cr models.ClusterRun) dto.ClusterRunResponse {
|
||||||
|
var finished *time.Time
|
||||||
|
if !cr.FinishedAt.IsZero() {
|
||||||
|
t := cr.FinishedAt
|
||||||
|
finished = &t
|
||||||
|
}
|
||||||
|
return dto.ClusterRunResponse{
|
||||||
|
ID: cr.ID,
|
||||||
|
OrganizationID: cr.OrganizationID,
|
||||||
|
ClusterID: cr.ClusterID,
|
||||||
|
Action: cr.Action,
|
||||||
|
Status: cr.Status,
|
||||||
|
Error: cr.Error,
|
||||||
|
CreatedAt: cr.CreatedAt,
|
||||||
|
UpdatedAt: cr.UpdatedAt,
|
||||||
|
FinishedAt: finished,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,7 +69,17 @@ func ListClusters(db *gorm.DB) http.HandlerFunc {
|
|||||||
|
|
||||||
out := make([]dto.ClusterResponse, 0, len(rows))
|
out := make([]dto.ClusterResponse, 0, len(rows))
|
||||||
for _, row := range rows {
|
for _, row := range rows {
|
||||||
out = append(out, clusterToDTO(row))
|
cr := clusterToDTO(row)
|
||||||
|
|
||||||
|
if row.EncryptedKubeconfig != "" && row.KubeIV != "" && row.KubeTag != "" {
|
||||||
|
kubeconfig, err := utils.DecryptForOrg(orgID, row.EncryptedKubeconfig, row.KubeIV, row.KubeTag, db)
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "kubeconfig_decrypt_failed", "failed to decrypt kubeconfig")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cr.Kubeconfig = &kubeconfig
|
||||||
|
}
|
||||||
|
out = append(out, cr)
|
||||||
}
|
}
|
||||||
utils.WriteJSON(w, http.StatusOK, out)
|
utils.WriteJSON(w, http.StatusOK, out)
|
||||||
}
|
}
|
||||||
@@ -131,7 +141,18 @@ func GetCluster(db *gorm.DB) http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.WriteJSON(w, http.StatusOK, clusterToDTO(cluster))
|
resp := clusterToDTO(cluster)
|
||||||
|
|
||||||
|
if cluster.EncryptedKubeconfig != "" && cluster.KubeIV != "" && cluster.KubeTag != "" {
|
||||||
|
kubeconfig, err := utils.DecryptForOrg(orgID, cluster.EncryptedKubeconfig, cluster.KubeIV, cluster.KubeTag, db)
|
||||||
|
if err != nil {
|
||||||
|
utils.WriteError(w, http.StatusInternalServerError, "kubeconfig_decrypt_failed", "failed to decrypt kubeconfig")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp.Kubeconfig = &kubeconfig
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.WriteJSON(w, http.StatusOK, resp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +210,8 @@ func CreateCluster(db *gorm.DB) http.HandlerFunc {
|
|||||||
LastError: "",
|
LastError: "",
|
||||||
CertificateKey: certificateKey,
|
CertificateKey: certificateKey,
|
||||||
RandomToken: randomToken,
|
RandomToken: randomToken,
|
||||||
|
DockerImage: in.DockerImage,
|
||||||
|
DockerTag: in.DockerTag,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := db.Create(&c).Error; err != nil {
|
if err := db.Create(&c).Error; err != nil {
|
||||||
@@ -262,6 +285,14 @@ func UpdateCluster(db *gorm.DB) http.HandlerFunc {
|
|||||||
cluster.Region = *in.Region
|
cluster.Region = *in.Region
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if in.DockerImage != nil {
|
||||||
|
cluster.DockerImage = *in.DockerImage
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.DockerTag != nil {
|
||||||
|
cluster.DockerTag = *in.DockerTag
|
||||||
|
}
|
||||||
|
|
||||||
if err := db.Save(&cluster).Error; err != nil {
|
if err := db.Save(&cluster).Error; err != nil {
|
||||||
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
|
||||||
return
|
return
|
||||||
@@ -1547,6 +1578,8 @@ func clusterToDTO(c models.Cluster) dto.ClusterResponse {
|
|||||||
RandomToken: c.RandomToken,
|
RandomToken: c.RandomToken,
|
||||||
CertificateKey: c.CertificateKey,
|
CertificateKey: c.CertificateKey,
|
||||||
NodePools: nps,
|
NodePools: nps,
|
||||||
|
DockerImage: c.DockerImage,
|
||||||
|
DockerTag: c.DockerTag,
|
||||||
CreatedAt: c.CreatedAt,
|
CreatedAt: c.CreatedAt,
|
||||||
UpdatedAt: c.UpdatedAt,
|
UpdatedAt: c.UpdatedAt,
|
||||||
}
|
}
|
||||||
|
|||||||
28
internal/handlers/dto/actions.go
Normal file
28
internal/handlers/dto/actions.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActionResponse struct {
|
||||||
|
ID uuid.UUID `json:"id" format:"uuid"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
MakeTarget string `json:"make_target"`
|
||||||
|
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateActionRequest struct {
|
||||||
|
Label string `json:"label"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
MakeTarget string `json:"make_target"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateActionRequest struct {
|
||||||
|
Label *string `json:"label,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
MakeTarget *string `json:"make_target,omitempty"`
|
||||||
|
}
|
||||||
19
internal/handlers/dto/cluster_runs.go
Normal file
19
internal/handlers/dto/cluster_runs.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClusterRunResponse struct {
|
||||||
|
ID uuid.UUID `json:"id" format:"uuid"`
|
||||||
|
OrganizationID uuid.UUID `json:"organization_id" format:"uuid"`
|
||||||
|
ClusterID uuid.UUID `json:"cluster_id" format:"uuid"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Error string `json:"error"`
|
||||||
|
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
|
||||||
|
FinishedAt *time.Time `json:"finished_at,omitempty" format:"date-time"`
|
||||||
|
}
|
||||||
@@ -22,6 +22,11 @@ type ClusterResponse struct {
|
|||||||
RandomToken string `json:"random_token"`
|
RandomToken string `json:"random_token"`
|
||||||
CertificateKey string `json:"certificate_key"`
|
CertificateKey string `json:"certificate_key"`
|
||||||
NodePools []NodePoolResponse `json:"node_pools,omitempty"`
|
NodePools []NodePoolResponse `json:"node_pools,omitempty"`
|
||||||
|
DockerImage string `json:"docker_image"`
|
||||||
|
DockerTag string `json:"docker_tag"`
|
||||||
|
Kubeconfig *string `json:"kubeconfig,omitempty"`
|
||||||
|
OrgKey *string `json:"org_key,omitempty"`
|
||||||
|
OrgSecret *string `json:"org_secret,omitempty"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -30,12 +35,16 @@ type CreateClusterRequest struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ClusterProvider string `json:"cluster_provider"`
|
ClusterProvider string `json:"cluster_provider"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
|
DockerImage string `json:"docker_image"`
|
||||||
|
DockerTag string `json:"docker_tag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateClusterRequest struct {
|
type UpdateClusterRequest struct {
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
ClusterProvider *string `json:"cluster_provider,omitempty"`
|
ClusterProvider *string `json:"cluster_provider,omitempty"`
|
||||||
Region *string `json:"region,omitempty"`
|
Region *string `json:"region,omitempty"`
|
||||||
|
DockerImage *string `json:"docker_image,omitempty"`
|
||||||
|
DockerTag *string `json:"docker_tag,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AttachCaptainDomainRequest struct {
|
type AttachCaptainDomainRequest struct {
|
||||||
|
|||||||
@@ -828,16 +828,16 @@ func ListNodePoolLabels(db *gorm.DB) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out := make([]dto.LabelResponse, 0, len(np.Taints))
|
out := make([]dto.LabelResponse, 0, len(np.Taints))
|
||||||
for _, taint := range np.Taints {
|
for _, label := range np.Labels {
|
||||||
out = append(out, dto.LabelResponse{
|
out = append(out, dto.LabelResponse{
|
||||||
AuditFields: common.AuditFields{
|
AuditFields: common.AuditFields{
|
||||||
ID: taint.ID,
|
ID: label.ID,
|
||||||
OrganizationID: taint.OrganizationID,
|
OrganizationID: label.OrganizationID,
|
||||||
CreatedAt: taint.CreatedAt,
|
CreatedAt: label.CreatedAt,
|
||||||
UpdatedAt: taint.UpdatedAt,
|
UpdatedAt: label.UpdatedAt,
|
||||||
},
|
},
|
||||||
Key: taint.Key,
|
Key: label.Key,
|
||||||
Value: taint.Value,
|
Value: label.Value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
utils.WriteJSON(w, http.StatusOK, out)
|
utils.WriteJSON(w, http.StatusOK, out)
|
||||||
|
|||||||
@@ -585,13 +585,22 @@ func CreateOrgKey(db *gorm.DB) http.HandlerFunc {
|
|||||||
exp = &e
|
exp = &e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prefix := orgKey
|
||||||
|
if len(prefix) > 12 {
|
||||||
|
prefix = prefix[:12]
|
||||||
|
}
|
||||||
|
|
||||||
rec := models.APIKey{
|
rec := models.APIKey{
|
||||||
OrgID: &oid,
|
OrgID: &oid,
|
||||||
Scope: "org",
|
Scope: "org",
|
||||||
|
Purpose: "user",
|
||||||
|
IsEphemeral: false,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
KeyHash: keyHash,
|
KeyHash: keyHash,
|
||||||
SecretHash: &secretHash,
|
SecretHash: &secretHash,
|
||||||
ExpiresAt: exp,
|
ExpiresAt: exp,
|
||||||
|
Revoked: false,
|
||||||
|
Prefix: &prefix,
|
||||||
}
|
}
|
||||||
if err := db.Create(&rec).Error; err != nil {
|
if err := db.Create(&rec).Error; err != nil {
|
||||||
utils.WriteError(w, 500, "db_error", err.Error())
|
utils.WriteError(w, 500, "db_error", err.Error())
|
||||||
|
|||||||
182
internal/mapper/cluster.go
Normal file
182
internal/mapper/cluster.go
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
package mapper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/glueops/autoglue/internal/common"
|
||||||
|
"github.com/glueops/autoglue/internal/handlers/dto"
|
||||||
|
"github.com/glueops/autoglue/internal/models"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ClusterToDTO(c models.Cluster) dto.ClusterResponse {
|
||||||
|
var bastion *dto.ServerResponse
|
||||||
|
if c.BastionServer != nil {
|
||||||
|
b := ServerToDTO(*c.BastionServer)
|
||||||
|
bastion = &b
|
||||||
|
}
|
||||||
|
|
||||||
|
var captainDomain *dto.DomainResponse
|
||||||
|
if c.CaptainDomainID != nil && c.CaptainDomain.ID != uuid.Nil {
|
||||||
|
dr := DomainToDTO(c.CaptainDomain)
|
||||||
|
captainDomain = &dr
|
||||||
|
}
|
||||||
|
|
||||||
|
var controlPlane *dto.RecordSetResponse
|
||||||
|
if c.ControlPlaneRecordSet != nil {
|
||||||
|
rr := RecordSetToDTO(*c.ControlPlaneRecordSet)
|
||||||
|
controlPlane = &rr
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfqdn *string
|
||||||
|
if captainDomain != nil && controlPlane != nil {
|
||||||
|
fq := fmt.Sprintf("%s.%s", controlPlane.Name, captainDomain.DomainName)
|
||||||
|
cfqdn = &fq
|
||||||
|
}
|
||||||
|
|
||||||
|
var appsLB *dto.LoadBalancerResponse
|
||||||
|
if c.AppsLoadBalancer != nil {
|
||||||
|
lr := LoadBalancerToDTO(*c.AppsLoadBalancer)
|
||||||
|
appsLB = &lr
|
||||||
|
}
|
||||||
|
|
||||||
|
var glueOpsLB *dto.LoadBalancerResponse
|
||||||
|
if c.GlueOpsLoadBalancer != nil {
|
||||||
|
lr := LoadBalancerToDTO(*c.GlueOpsLoadBalancer)
|
||||||
|
glueOpsLB = &lr
|
||||||
|
}
|
||||||
|
|
||||||
|
nps := make([]dto.NodePoolResponse, 0, len(c.NodePools))
|
||||||
|
for _, np := range c.NodePools {
|
||||||
|
nps = append(nps, NodePoolToDTO(np))
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ClusterResponse{
|
||||||
|
ID: c.ID,
|
||||||
|
Name: c.Name,
|
||||||
|
CaptainDomain: captainDomain,
|
||||||
|
ControlPlaneRecordSet: controlPlane,
|
||||||
|
ControlPlaneFQDN: cfqdn,
|
||||||
|
AppsLoadBalancer: appsLB,
|
||||||
|
GlueOpsLoadBalancer: glueOpsLB,
|
||||||
|
BastionServer: bastion,
|
||||||
|
Provider: c.Provider,
|
||||||
|
Region: c.Region,
|
||||||
|
Status: c.Status,
|
||||||
|
LastError: c.LastError,
|
||||||
|
RandomToken: c.RandomToken,
|
||||||
|
CertificateKey: c.CertificateKey,
|
||||||
|
NodePools: nps,
|
||||||
|
DockerImage: c.DockerImage,
|
||||||
|
DockerTag: c.DockerTag,
|
||||||
|
CreatedAt: c.CreatedAt,
|
||||||
|
UpdatedAt: c.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NodePoolToDTO(np models.NodePool) dto.NodePoolResponse {
|
||||||
|
labels := make([]dto.LabelResponse, 0, len(np.Labels))
|
||||||
|
for _, l := range np.Labels {
|
||||||
|
labels = append(labels, dto.LabelResponse{
|
||||||
|
Key: l.Key,
|
||||||
|
Value: l.Value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
annotations := make([]dto.AnnotationResponse, 0, len(np.Annotations))
|
||||||
|
for _, a := range np.Annotations {
|
||||||
|
annotations = append(annotations, dto.AnnotationResponse{
|
||||||
|
Key: a.Key,
|
||||||
|
Value: a.Value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
taints := make([]dto.TaintResponse, 0, len(np.Taints))
|
||||||
|
for _, t := range np.Taints {
|
||||||
|
taints = append(taints, dto.TaintResponse{
|
||||||
|
Key: t.Key,
|
||||||
|
Value: t.Value,
|
||||||
|
Effect: t.Effect,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
servers := make([]dto.ServerResponse, 0, len(np.Servers))
|
||||||
|
for _, s := range np.Servers {
|
||||||
|
servers = append(servers, ServerToDTO(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.NodePoolResponse{
|
||||||
|
AuditFields: common.AuditFields{
|
||||||
|
ID: np.ID,
|
||||||
|
OrganizationID: np.OrganizationID,
|
||||||
|
CreatedAt: np.CreatedAt,
|
||||||
|
UpdatedAt: np.UpdatedAt,
|
||||||
|
},
|
||||||
|
Name: np.Name,
|
||||||
|
Role: dto.NodeRole(np.Role),
|
||||||
|
Labels: labels,
|
||||||
|
Annotations: annotations,
|
||||||
|
Taints: taints,
|
||||||
|
Servers: servers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ServerToDTO(s models.Server) dto.ServerResponse {
|
||||||
|
return dto.ServerResponse{
|
||||||
|
ID: s.ID,
|
||||||
|
Hostname: s.Hostname,
|
||||||
|
PrivateIPAddress: s.PrivateIPAddress,
|
||||||
|
PublicIPAddress: s.PublicIPAddress,
|
||||||
|
Role: s.Role,
|
||||||
|
Status: s.Status,
|
||||||
|
SSHUser: s.SSHUser,
|
||||||
|
SshKeyID: s.SshKeyID,
|
||||||
|
CreatedAt: s.CreatedAt.UTC().Format(time.RFC3339),
|
||||||
|
UpdatedAt: s.UpdatedAt.UTC().Format(time.RFC3339),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DomainToDTO(d models.Domain) dto.DomainResponse {
|
||||||
|
return dto.DomainResponse{
|
||||||
|
ID: d.ID.String(),
|
||||||
|
OrganizationID: d.OrganizationID.String(),
|
||||||
|
DomainName: d.DomainName,
|
||||||
|
ZoneID: d.ZoneID,
|
||||||
|
Status: d.Status,
|
||||||
|
LastError: d.LastError,
|
||||||
|
CredentialID: d.CredentialID.String(),
|
||||||
|
CreatedAt: d.CreatedAt.UTC().Format(time.RFC3339),
|
||||||
|
UpdatedAt: d.UpdatedAt.UTC().Format(time.RFC3339),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RecordSetToDTO(rs models.RecordSet) dto.RecordSetResponse {
|
||||||
|
return dto.RecordSetResponse{
|
||||||
|
ID: rs.ID.String(),
|
||||||
|
DomainID: rs.DomainID.String(),
|
||||||
|
Name: rs.Name,
|
||||||
|
Type: rs.Type,
|
||||||
|
TTL: rs.TTL,
|
||||||
|
Values: []byte(rs.Values),
|
||||||
|
Fingerprint: rs.Fingerprint,
|
||||||
|
Status: rs.Status,
|
||||||
|
Owner: rs.Owner,
|
||||||
|
LastError: rs.LastError,
|
||||||
|
CreatedAt: rs.CreatedAt.UTC().Format(time.RFC3339),
|
||||||
|
UpdatedAt: rs.UpdatedAt.UTC().Format(time.RFC3339),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadBalancerToDTO(lb models.LoadBalancer) dto.LoadBalancerResponse {
|
||||||
|
return dto.LoadBalancerResponse{
|
||||||
|
ID: lb.ID,
|
||||||
|
OrganizationID: lb.OrganizationID,
|
||||||
|
Name: lb.Name,
|
||||||
|
Kind: lb.Kind,
|
||||||
|
PublicIPAddress: lb.PublicIPAddress,
|
||||||
|
PrivateIPAddress: lb.PrivateIPAddress,
|
||||||
|
CreatedAt: lb.CreatedAt,
|
||||||
|
UpdatedAt: lb.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
16
internal/models/action.go
Normal file
16
internal/models/action.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Action struct {
|
||||||
|
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"`
|
||||||
|
Label string `gorm:"type:varchar(255);not null;uniqueIndex" json:"label"`
|
||||||
|
Description string `gorm:"type:text;not null" json:"description"`
|
||||||
|
MakeTarget string `gorm:"type:varchar(255);not null;uniqueIndex" json:"make_target"`
|
||||||
|
CreatedAt time.Time `json:"created_at,omitempty" gorm:"type:timestamptz;column:created_at;not null;default:now()" format:"date-time"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at,omitempty" gorm:"type:timestamptz;autoUpdateTime;column:updated_at;not null;default:now()" format:"date-time"`
|
||||||
|
}
|
||||||
@@ -8,12 +8,15 @@ import (
|
|||||||
|
|
||||||
type APIKey struct {
|
type APIKey struct {
|
||||||
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"`
|
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"`
|
||||||
|
OrgID *uuid.UUID `json:"org_id,omitempty" format:"uuid"`
|
||||||
|
Scope string `gorm:"not null;default:''" json:"scope"`
|
||||||
|
Purpose string `json:"purpose"`
|
||||||
|
ClusterID *uuid.UUID `json:"cluster_id,omitempty"`
|
||||||
|
IsEphemeral bool `json:"is_ephemeral"`
|
||||||
Name string `gorm:"not null;default:''" json:"name"`
|
Name string `gorm:"not null;default:''" json:"name"`
|
||||||
KeyHash string `gorm:"uniqueIndex;not null" json:"-"`
|
KeyHash string `gorm:"uniqueIndex;not null" json:"-"`
|
||||||
Scope string `gorm:"not null;default:''" json:"scope"`
|
|
||||||
UserID *uuid.UUID `json:"user_id,omitempty" format:"uuid"`
|
|
||||||
OrgID *uuid.UUID `json:"org_id,omitempty" format:"uuid"`
|
|
||||||
SecretHash *string `json:"-"`
|
SecretHash *string `json:"-"`
|
||||||
|
UserID *uuid.UUID `json:"user_id,omitempty" format:"uuid"`
|
||||||
ExpiresAt *time.Time `json:"expires_at,omitempty" format:"date-time"`
|
ExpiresAt *time.Time `json:"expires_at,omitempty" format:"date-time"`
|
||||||
Revoked bool `gorm:"not null;default:false" json:"revoked"`
|
Revoked bool `gorm:"not null;default:false" json:"revoked"`
|
||||||
Prefix *string `json:"prefix,omitempty"`
|
Prefix *string `json:"prefix,omitempty"`
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const (
|
|||||||
ClusterStatusProvisioning = "provisioning"
|
ClusterStatusProvisioning = "provisioning"
|
||||||
ClusterStatusReady = "ready"
|
ClusterStatusReady = "ready"
|
||||||
ClusterStatusFailed = "failed" // provisioning/runtime failure
|
ClusterStatusFailed = "failed" // provisioning/runtime failure
|
||||||
|
ClusterStatusBootstrapping = "bootstrapping"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
@@ -40,6 +41,8 @@ type Cluster struct {
|
|||||||
EncryptedKubeconfig string `gorm:"type:text" json:"-"`
|
EncryptedKubeconfig string `gorm:"type:text" json:"-"`
|
||||||
KubeIV string `json:"-"`
|
KubeIV string `json:"-"`
|
||||||
KubeTag string `json:"-"`
|
KubeTag string `json:"-"`
|
||||||
|
DockerImage string `json:"docker_image"`
|
||||||
|
DockerTag string `json:"docker_tag"`
|
||||||
CreatedAt time.Time `json:"created_at,omitempty" gorm:"type:timestamptz;column:created_at;not null;default:now()"`
|
CreatedAt time.Time `json:"created_at,omitempty" gorm:"type:timestamptz;column:created_at;not null;default:now()"`
|
||||||
UpdatedAt time.Time `json:"updated_at,omitempty" gorm:"type:timestamptz;autoUpdateTime;column:updated_at;not null;default:now()"`
|
UpdatedAt time.Time `json:"updated_at,omitempty" gorm:"type:timestamptz;autoUpdateTime;column:updated_at;not null;default:now()"`
|
||||||
}
|
}
|
||||||
|
|||||||
27
internal/models/cluster_runs.go
Normal file
27
internal/models/cluster_runs.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ClusterRunStatusQueued = "queued"
|
||||||
|
ClusterRunStatusRunning = "running"
|
||||||
|
ClusterRunStatusSuccess = "success"
|
||||||
|
ClusterRunStatusFailed = "failed"
|
||||||
|
ClusterRunStatusCanceled = "canceled"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClusterRun struct {
|
||||||
|
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"`
|
||||||
|
OrganizationID uuid.UUID `json:"organization_id" gorm:"type:uuid;index"`
|
||||||
|
ClusterID uuid.UUID `json:"cluster_id" gorm:"type:uuid;index"`
|
||||||
|
Action string `json:"action" gorm:"type:text;not null"`
|
||||||
|
Status string `json:"status" gorm:"type:text;not null"`
|
||||||
|
Error string `json:"error" gorm:"type:text;not null"`
|
||||||
|
CreatedAt time.Time `json:"created_at,omitempty" gorm:"type:timestamptz;column:created_at;not null;default:now()" format:"date-time"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at,omitempty" gorm:"type:timestamptz;autoUpdateTime;column:updated_at;not null;default:now()" format:"date-time"`
|
||||||
|
FinishedAt time.Time `json:"finished_at,omitempty" gorm:"type:timestamptz" format:"date-time"`
|
||||||
|
}
|
||||||
BIN
internal/web/dist/assets/index-BwyDjDcq.js.br
vendored
BIN
internal/web/dist/assets/index-BwyDjDcq.js.br
vendored
Binary file not shown.
BIN
internal/web/dist/assets/index-BwyDjDcq.js.gz
vendored
BIN
internal/web/dist/assets/index-BwyDjDcq.js.gz
vendored
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
internal/web/dist/assets/index-CyGsiYei.js.br
vendored
Normal file
BIN
internal/web/dist/assets/index-CyGsiYei.js.br
vendored
Normal file
Binary file not shown.
BIN
internal/web/dist/assets/index-CyGsiYei.js.gz
vendored
Normal file
BIN
internal/web/dist/assets/index-CyGsiYei.js.gz
vendored
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
internal/web/dist/assets/index-VHZG0dIU.css.gz
vendored
BIN
internal/web/dist/assets/index-VHZG0dIU.css.gz
vendored
Binary file not shown.
BIN
internal/web/dist/assets/react-Dt2M6tWj.js.gz
vendored
BIN
internal/web/dist/assets/react-Dt2M6tWj.js.gz
vendored
Binary file not shown.
2
internal/web/dist/index.html
vendored
2
internal/web/dist/index.html
vendored
@@ -5,7 +5,7 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>AutoGlue</title>
|
<title>AutoGlue</title>
|
||||||
<script type="module" crossorigin src="/assets/index-BwyDjDcq.js"></script>
|
<script type="module" crossorigin src="/assets/index-CyGsiYei.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="/assets/react-Dt2M6tWj.js">
|
<link rel="modulepreload" crossorigin href="/assets/react-Dt2M6tWj.js">
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-VHZG0dIU.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-VHZG0dIU.css">
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
BIN
internal/web/dist/index.html.br
vendored
BIN
internal/web/dist/index.html.br
vendored
Binary file not shown.
BIN
internal/web/dist/index.html.gz
vendored
BIN
internal/web/dist/index.html.gz
vendored
Binary file not shown.
@@ -12,6 +12,8 @@
|
|||||||
| `control_plane_fqdn` | string |
|
| `control_plane_fqdn` | string |
|
||||||
| `control_plane_record_set` | [DtoRecordSetResponse](DtoRecordSetResponse.md) |
|
| `control_plane_record_set` | [DtoRecordSetResponse](DtoRecordSetResponse.md) |
|
||||||
| `created_at` | string |
|
| `created_at` | string |
|
||||||
|
| `docker_image` | string |
|
||||||
|
| `docker_tag` | string |
|
||||||
| `glueops_load_balancer` | [DtoLoadBalancerResponse](DtoLoadBalancerResponse.md) |
|
| `glueops_load_balancer` | [DtoLoadBalancerResponse](DtoLoadBalancerResponse.md) |
|
||||||
| `id` | string |
|
| `id` | string |
|
||||||
| `last_error` | string |
|
| `last_error` | string |
|
||||||
@@ -37,6 +39,8 @@ const example = {
|
|||||||
control_plane_fqdn: null,
|
control_plane_fqdn: null,
|
||||||
control_plane_record_set: null,
|
control_plane_record_set: null,
|
||||||
created_at: null,
|
created_at: null,
|
||||||
|
docker_image: null,
|
||||||
|
docker_tag: null,
|
||||||
glueops_load_balancer: null,
|
glueops_load_balancer: null,
|
||||||
id: null,
|
id: null,
|
||||||
last_error: null,
|
last_error: null,
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
| Name | Type |
|
| Name | Type |
|
||||||
| ------------------ | ------ |
|
| ------------------ | ------ |
|
||||||
| `cluster_provider` | string |
|
| `cluster_provider` | string |
|
||||||
|
| `docker_image` | string |
|
||||||
|
| `docker_tag` | string |
|
||||||
| `name` | string |
|
| `name` | string |
|
||||||
| `region` | string |
|
| `region` | string |
|
||||||
|
|
||||||
@@ -16,6 +18,8 @@ import type { DtoCreateClusterRequest } from "@glueops/autoglue-sdk-go";
|
|||||||
// TODO: Update the object below with actual values
|
// TODO: Update the object below with actual values
|
||||||
const example = {
|
const example = {
|
||||||
cluster_provider: null,
|
cluster_provider: null,
|
||||||
|
docker_image: null,
|
||||||
|
docker_tag: null,
|
||||||
name: null,
|
name: null,
|
||||||
region: null,
|
region: null,
|
||||||
} satisfies DtoCreateClusterRequest;
|
} satisfies DtoCreateClusterRequest;
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
| Name | Type |
|
| Name | Type |
|
||||||
| ------------------ | ------ |
|
| ------------------ | ------ |
|
||||||
| `cluster_provider` | string |
|
| `cluster_provider` | string |
|
||||||
|
| `docker_image` | string |
|
||||||
|
| `docker_tag` | string |
|
||||||
| `name` | string |
|
| `name` | string |
|
||||||
| `region` | string |
|
| `region` | string |
|
||||||
|
|
||||||
@@ -16,6 +18,8 @@ import type { DtoUpdateClusterRequest } from "@glueops/autoglue-sdk-go";
|
|||||||
// TODO: Update the object below with actual values
|
// TODO: Update the object below with actual values
|
||||||
const example = {
|
const example = {
|
||||||
cluster_provider: null,
|
cluster_provider: null,
|
||||||
|
docker_image: null,
|
||||||
|
docker_tag: null,
|
||||||
name: null,
|
name: null,
|
||||||
region: null,
|
region: null,
|
||||||
} satisfies DtoUpdateClusterRequest;
|
} satisfies DtoUpdateClusterRequest;
|
||||||
|
|||||||
@@ -16,6 +16,6 @@
|
|||||||
"prepare": "npm run build"
|
"prepare": "npm run build"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "5.9.3"
|
"typescript": "^4.0 || ^5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {DtoAnnotationResponse, DtoCreateAnnotationRequest, DtoUpdateAnnotationRequest,} from "../models/index";
|
import type {
|
||||||
|
DtoAnnotationResponse,
|
||||||
|
DtoCreateAnnotationRequest,
|
||||||
|
DtoUpdateAnnotationRequest,
|
||||||
|
} from "../models/index";
|
||||||
import {
|
import {
|
||||||
DtoAnnotationResponseFromJSON,
|
DtoAnnotationResponseFromJSON,
|
||||||
|
DtoAnnotationResponseToJSON,
|
||||||
|
DtoCreateAnnotationRequestFromJSON,
|
||||||
DtoCreateAnnotationRequestToJSON,
|
DtoCreateAnnotationRequestToJSON,
|
||||||
|
DtoUpdateAnnotationRequestFromJSON,
|
||||||
DtoUpdateAnnotationRequestToJSON,
|
DtoUpdateAnnotationRequestToJSON,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {DtoEnqueueRequest, DtoJob, DtoPageJob, DtoQueueInfo,} from "../models/index";
|
import type {
|
||||||
import {DtoEnqueueRequestToJSON, DtoJobFromJSON, DtoPageJobFromJSON, DtoQueueInfoFromJSON,} from "../models/index";
|
DtoEnqueueRequest,
|
||||||
|
DtoJob,
|
||||||
|
DtoPageJob,
|
||||||
|
DtoQueueInfo,
|
||||||
|
} from "../models/index";
|
||||||
|
import {
|
||||||
|
DtoEnqueueRequestFromJSON,
|
||||||
|
DtoEnqueueRequestToJSON,
|
||||||
|
DtoJobFromJSON,
|
||||||
|
DtoJobToJSON,
|
||||||
|
DtoPageJobFromJSON,
|
||||||
|
DtoPageJobToJSON,
|
||||||
|
DtoQueueInfoFromJSON,
|
||||||
|
DtoQueueInfoToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
export interface AdminCancelArcherJobRequest {
|
export interface AdminCancelArcherJobRequest {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -13,13 +13,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {DtoAuthStartResponse, DtoJWKS, DtoLogoutRequest, DtoRefreshRequest, DtoTokenPair,} from "../models/index";
|
import type {
|
||||||
|
DtoAuthStartResponse,
|
||||||
|
DtoJWKS,
|
||||||
|
DtoLogoutRequest,
|
||||||
|
DtoRefreshRequest,
|
||||||
|
DtoTokenPair,
|
||||||
|
} from "../models/index";
|
||||||
import {
|
import {
|
||||||
DtoAuthStartResponseFromJSON,
|
DtoAuthStartResponseFromJSON,
|
||||||
|
DtoAuthStartResponseToJSON,
|
||||||
DtoJWKSFromJSON,
|
DtoJWKSFromJSON,
|
||||||
|
DtoJWKSToJSON,
|
||||||
|
DtoLogoutRequestFromJSON,
|
||||||
DtoLogoutRequestToJSON,
|
DtoLogoutRequestToJSON,
|
||||||
|
DtoRefreshRequestFromJSON,
|
||||||
DtoRefreshRequestToJSON,
|
DtoRefreshRequestToJSON,
|
||||||
DtoTokenPairFromJSON,
|
DtoTokenPairFromJSON,
|
||||||
|
DtoTokenPairToJSON,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
|
|
||||||
export interface AuthCallbackRequest {
|
export interface AuthCallbackRequest {
|
||||||
|
|||||||
@@ -25,14 +25,23 @@ import type {
|
|||||||
DtoUpdateClusterRequest,
|
DtoUpdateClusterRequest,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
import {
|
import {
|
||||||
|
DtoAttachBastionRequestFromJSON,
|
||||||
DtoAttachBastionRequestToJSON,
|
DtoAttachBastionRequestToJSON,
|
||||||
|
DtoAttachCaptainDomainRequestFromJSON,
|
||||||
DtoAttachCaptainDomainRequestToJSON,
|
DtoAttachCaptainDomainRequestToJSON,
|
||||||
|
DtoAttachLoadBalancerRequestFromJSON,
|
||||||
DtoAttachLoadBalancerRequestToJSON,
|
DtoAttachLoadBalancerRequestToJSON,
|
||||||
|
DtoAttachNodePoolRequestFromJSON,
|
||||||
DtoAttachNodePoolRequestToJSON,
|
DtoAttachNodePoolRequestToJSON,
|
||||||
|
DtoAttachRecordSetRequestFromJSON,
|
||||||
DtoAttachRecordSetRequestToJSON,
|
DtoAttachRecordSetRequestToJSON,
|
||||||
DtoClusterResponseFromJSON,
|
DtoClusterResponseFromJSON,
|
||||||
|
DtoClusterResponseToJSON,
|
||||||
|
DtoCreateClusterRequestFromJSON,
|
||||||
DtoCreateClusterRequestToJSON,
|
DtoCreateClusterRequestToJSON,
|
||||||
|
DtoSetKubeconfigRequestFromJSON,
|
||||||
DtoSetKubeconfigRequestToJSON,
|
DtoSetKubeconfigRequestToJSON,
|
||||||
|
DtoUpdateClusterRequestFromJSON,
|
||||||
DtoUpdateClusterRequestToJSON,
|
DtoUpdateClusterRequestToJSON,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {DtoCreateCredentialRequest, DtoCredentialOut, DtoUpdateCredentialRequest,} from "../models/index";
|
import type {
|
||||||
|
DtoCreateCredentialRequest,
|
||||||
|
DtoCredentialOut,
|
||||||
|
DtoUpdateCredentialRequest,
|
||||||
|
} from "../models/index";
|
||||||
import {
|
import {
|
||||||
|
DtoCreateCredentialRequestFromJSON,
|
||||||
DtoCreateCredentialRequestToJSON,
|
DtoCreateCredentialRequestToJSON,
|
||||||
DtoCredentialOutFromJSON,
|
DtoCredentialOutFromJSON,
|
||||||
|
DtoCredentialOutToJSON,
|
||||||
|
DtoUpdateCredentialRequestFromJSON,
|
||||||
DtoUpdateCredentialRequestToJSON,
|
DtoUpdateCredentialRequestToJSON,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,17 @@ import type {
|
|||||||
DtoUpdateRecordSetRequest,
|
DtoUpdateRecordSetRequest,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
import {
|
import {
|
||||||
|
DtoCreateDomainRequestFromJSON,
|
||||||
DtoCreateDomainRequestToJSON,
|
DtoCreateDomainRequestToJSON,
|
||||||
|
DtoCreateRecordSetRequestFromJSON,
|
||||||
DtoCreateRecordSetRequestToJSON,
|
DtoCreateRecordSetRequestToJSON,
|
||||||
DtoDomainResponseFromJSON,
|
DtoDomainResponseFromJSON,
|
||||||
|
DtoDomainResponseToJSON,
|
||||||
DtoRecordSetResponseFromJSON,
|
DtoRecordSetResponseFromJSON,
|
||||||
|
DtoRecordSetResponseToJSON,
|
||||||
|
DtoUpdateDomainRequestFromJSON,
|
||||||
DtoUpdateDomainRequestToJSON,
|
DtoUpdateDomainRequestToJSON,
|
||||||
|
DtoUpdateRecordSetRequestFromJSON,
|
||||||
DtoUpdateRecordSetRequestToJSON,
|
DtoUpdateRecordSetRequestToJSON,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,10 @@
|
|||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type { HandlersHealthStatus } from "../models/index";
|
import type { HandlersHealthStatus } from "../models/index";
|
||||||
import {HandlersHealthStatusFromJSON,} from "../models/index";
|
import {
|
||||||
|
HandlersHealthStatusFromJSON,
|
||||||
|
HandlersHealthStatusToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -13,8 +13,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {DtoCreateLabelRequest, DtoLabelResponse, DtoUpdateLabelRequest,} from "../models/index";
|
import type {
|
||||||
import {DtoCreateLabelRequestToJSON, DtoLabelResponseFromJSON, DtoUpdateLabelRequestToJSON,} from "../models/index";
|
DtoCreateLabelRequest,
|
||||||
|
DtoLabelResponse,
|
||||||
|
DtoUpdateLabelRequest,
|
||||||
|
} from "../models/index";
|
||||||
|
import {
|
||||||
|
DtoCreateLabelRequestFromJSON,
|
||||||
|
DtoCreateLabelRequestToJSON,
|
||||||
|
DtoLabelResponseFromJSON,
|
||||||
|
DtoLabelResponseToJSON,
|
||||||
|
DtoUpdateLabelRequestFromJSON,
|
||||||
|
DtoUpdateLabelRequestToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
export interface CreateLabelRequest {
|
export interface CreateLabelRequest {
|
||||||
dtoCreateLabelRequest: DtoCreateLabelRequest;
|
dtoCreateLabelRequest: DtoCreateLabelRequest;
|
||||||
|
|||||||
@@ -19,8 +19,11 @@ import type {
|
|||||||
DtoUpdateLoadBalancerRequest,
|
DtoUpdateLoadBalancerRequest,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
import {
|
import {
|
||||||
|
DtoCreateLoadBalancerRequestFromJSON,
|
||||||
DtoCreateLoadBalancerRequestToJSON,
|
DtoCreateLoadBalancerRequestToJSON,
|
||||||
DtoLoadBalancerResponseFromJSON,
|
DtoLoadBalancerResponseFromJSON,
|
||||||
|
DtoLoadBalancerResponseToJSON,
|
||||||
|
DtoUpdateLoadBalancerRequestFromJSON,
|
||||||
DtoUpdateLoadBalancerRequestToJSON,
|
DtoUpdateLoadBalancerRequestToJSON,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {HandlersCreateUserKeyRequest, HandlersUserAPIKeyOut,} from "../models/index";
|
import type {
|
||||||
import {HandlersCreateUserKeyRequestToJSON, HandlersUserAPIKeyOutFromJSON,} from "../models/index";
|
HandlersCreateUserKeyRequest,
|
||||||
|
HandlersUserAPIKeyOut,
|
||||||
|
} from "../models/index";
|
||||||
|
import {
|
||||||
|
HandlersCreateUserKeyRequestFromJSON,
|
||||||
|
HandlersCreateUserKeyRequestToJSON,
|
||||||
|
HandlersUserAPIKeyOutFromJSON,
|
||||||
|
HandlersUserAPIKeyOutToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
export interface CreateUserAPIKeyRequest {
|
export interface CreateUserAPIKeyRequest {
|
||||||
handlersCreateUserKeyRequest: HandlersCreateUserKeyRequest;
|
handlersCreateUserKeyRequest: HandlersCreateUserKeyRequest;
|
||||||
|
|||||||
@@ -13,8 +13,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {HandlersMeResponse, HandlersUpdateMeRequest, ModelsUser,} from "../models/index";
|
import type {
|
||||||
import {HandlersMeResponseFromJSON, HandlersUpdateMeRequestToJSON, ModelsUserFromJSON,} from "../models/index";
|
HandlersMeResponse,
|
||||||
|
HandlersUpdateMeRequest,
|
||||||
|
ModelsUser,
|
||||||
|
} from "../models/index";
|
||||||
|
import {
|
||||||
|
HandlersMeResponseFromJSON,
|
||||||
|
HandlersMeResponseToJSON,
|
||||||
|
HandlersUpdateMeRequestFromJSON,
|
||||||
|
HandlersUpdateMeRequestToJSON,
|
||||||
|
ModelsUserFromJSON,
|
||||||
|
ModelsUserToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
export interface UpdateMeRequest {
|
export interface UpdateMeRequest {
|
||||||
handlersUpdateMeRequest: HandlersUpdateMeRequest;
|
handlersUpdateMeRequest: HandlersUpdateMeRequest;
|
||||||
|
|||||||
@@ -14,7 +14,10 @@
|
|||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type { HandlersVersionResponse } from "../models/index";
|
import type { HandlersVersionResponse } from "../models/index";
|
||||||
import {HandlersVersionResponseFromJSON,} from "../models/index";
|
import {
|
||||||
|
HandlersVersionResponseFromJSON,
|
||||||
|
HandlersVersionResponseToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -28,15 +28,26 @@ import type {
|
|||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
import {
|
import {
|
||||||
DtoAnnotationResponseFromJSON,
|
DtoAnnotationResponseFromJSON,
|
||||||
|
DtoAnnotationResponseToJSON,
|
||||||
|
DtoAttachAnnotationsRequestFromJSON,
|
||||||
DtoAttachAnnotationsRequestToJSON,
|
DtoAttachAnnotationsRequestToJSON,
|
||||||
|
DtoAttachLabelsRequestFromJSON,
|
||||||
DtoAttachLabelsRequestToJSON,
|
DtoAttachLabelsRequestToJSON,
|
||||||
|
DtoAttachServersRequestFromJSON,
|
||||||
DtoAttachServersRequestToJSON,
|
DtoAttachServersRequestToJSON,
|
||||||
|
DtoAttachTaintsRequestFromJSON,
|
||||||
DtoAttachTaintsRequestToJSON,
|
DtoAttachTaintsRequestToJSON,
|
||||||
|
DtoCreateNodePoolRequestFromJSON,
|
||||||
DtoCreateNodePoolRequestToJSON,
|
DtoCreateNodePoolRequestToJSON,
|
||||||
DtoLabelResponseFromJSON,
|
DtoLabelResponseFromJSON,
|
||||||
|
DtoLabelResponseToJSON,
|
||||||
DtoNodePoolResponseFromJSON,
|
DtoNodePoolResponseFromJSON,
|
||||||
|
DtoNodePoolResponseToJSON,
|
||||||
DtoServerResponseFromJSON,
|
DtoServerResponseFromJSON,
|
||||||
|
DtoServerResponseToJSON,
|
||||||
DtoTaintResponseFromJSON,
|
DtoTaintResponseFromJSON,
|
||||||
|
DtoTaintResponseToJSON,
|
||||||
|
DtoUpdateNodePoolRequestFromJSON,
|
||||||
DtoUpdateNodePoolRequestToJSON,
|
DtoUpdateNodePoolRequestToJSON,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
|
|
||||||
|
|||||||
@@ -22,16 +22,27 @@ import type {
|
|||||||
HandlersOrgUpdateReq,
|
HandlersOrgUpdateReq,
|
||||||
ModelsAPIKey,
|
ModelsAPIKey,
|
||||||
ModelsOrganization,
|
ModelsOrganization,
|
||||||
|
UtilsErrorResponse,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
import {
|
import {
|
||||||
HandlersMemberOutFromJSON,
|
HandlersMemberOutFromJSON,
|
||||||
|
HandlersMemberOutToJSON,
|
||||||
|
HandlersMemberUpsertReqFromJSON,
|
||||||
HandlersMemberUpsertReqToJSON,
|
HandlersMemberUpsertReqToJSON,
|
||||||
|
HandlersOrgCreateReqFromJSON,
|
||||||
HandlersOrgCreateReqToJSON,
|
HandlersOrgCreateReqToJSON,
|
||||||
|
HandlersOrgKeyCreateReqFromJSON,
|
||||||
HandlersOrgKeyCreateReqToJSON,
|
HandlersOrgKeyCreateReqToJSON,
|
||||||
HandlersOrgKeyCreateRespFromJSON,
|
HandlersOrgKeyCreateRespFromJSON,
|
||||||
|
HandlersOrgKeyCreateRespToJSON,
|
||||||
|
HandlersOrgUpdateReqFromJSON,
|
||||||
HandlersOrgUpdateReqToJSON,
|
HandlersOrgUpdateReqToJSON,
|
||||||
ModelsAPIKeyFromJSON,
|
ModelsAPIKeyFromJSON,
|
||||||
|
ModelsAPIKeyToJSON,
|
||||||
ModelsOrganizationFromJSON,
|
ModelsOrganizationFromJSON,
|
||||||
|
ModelsOrganizationToJSON,
|
||||||
|
UtilsErrorResponseFromJSON,
|
||||||
|
UtilsErrorResponseToJSON,
|
||||||
} from "../models/index";
|
} from "../models/index";
|
||||||
|
|
||||||
export interface AddOrUpdateMemberRequest {
|
export interface AddOrUpdateMemberRequest {
|
||||||
|
|||||||
@@ -13,8 +13,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {DtoCreateServerRequest, DtoServerResponse, DtoUpdateServerRequest,} from "../models/index";
|
import type {
|
||||||
import {DtoCreateServerRequestToJSON, DtoServerResponseFromJSON, DtoUpdateServerRequestToJSON,} from "../models/index";
|
DtoCreateServerRequest,
|
||||||
|
DtoServerResponse,
|
||||||
|
DtoUpdateServerRequest,
|
||||||
|
} from "../models/index";
|
||||||
|
import {
|
||||||
|
DtoCreateServerRequestFromJSON,
|
||||||
|
DtoCreateServerRequestToJSON,
|
||||||
|
DtoServerResponseFromJSON,
|
||||||
|
DtoServerResponseToJSON,
|
||||||
|
DtoUpdateServerRequestFromJSON,
|
||||||
|
DtoUpdateServerRequestToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
export interface CreateServerRequest {
|
export interface CreateServerRequest {
|
||||||
dtoCreateServerRequest: DtoCreateServerRequest;
|
dtoCreateServerRequest: DtoCreateServerRequest;
|
||||||
|
|||||||
@@ -13,8 +13,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {DtoCreateSSHRequest, DtoSshResponse, GetSSHKey200Response,} from "../models/index";
|
import type {
|
||||||
import {DtoCreateSSHRequestToJSON, DtoSshResponseFromJSON, GetSSHKey200ResponseFromJSON,} from "../models/index";
|
DtoCreateSSHRequest,
|
||||||
|
DtoSshResponse,
|
||||||
|
GetSSHKey200Response,
|
||||||
|
} from "../models/index";
|
||||||
|
import {
|
||||||
|
DtoCreateSSHRequestFromJSON,
|
||||||
|
DtoCreateSSHRequestToJSON,
|
||||||
|
DtoSshResponseFromJSON,
|
||||||
|
DtoSshResponseToJSON,
|
||||||
|
GetSSHKey200ResponseFromJSON,
|
||||||
|
GetSSHKey200ResponseToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
export interface CreateSSHKeyRequest {
|
export interface CreateSSHKeyRequest {
|
||||||
dtoCreateSSHRequest: DtoCreateSSHRequest;
|
dtoCreateSSHRequest: DtoCreateSSHRequest;
|
||||||
|
|||||||
@@ -13,8 +13,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as runtime from "../runtime";
|
import * as runtime from "../runtime";
|
||||||
import type {DtoCreateTaintRequest, DtoTaintResponse, DtoUpdateTaintRequest,} from "../models/index";
|
import type {
|
||||||
import {DtoCreateTaintRequestToJSON, DtoTaintResponseFromJSON, DtoUpdateTaintRequestToJSON,} from "../models/index";
|
DtoCreateTaintRequest,
|
||||||
|
DtoTaintResponse,
|
||||||
|
DtoUpdateTaintRequest,
|
||||||
|
} from "../models/index";
|
||||||
|
import {
|
||||||
|
DtoCreateTaintRequestFromJSON,
|
||||||
|
DtoCreateTaintRequestToJSON,
|
||||||
|
DtoTaintResponseFromJSON,
|
||||||
|
DtoTaintResponseToJSON,
|
||||||
|
DtoUpdateTaintRequestFromJSON,
|
||||||
|
DtoUpdateTaintRequestToJSON,
|
||||||
|
} from "../models/index";
|
||||||
|
|
||||||
export interface CreateTaintRequest {
|
export interface CreateTaintRequest {
|
||||||
dtoCreateTaintRequest: DtoCreateTaintRequest;
|
dtoCreateTaintRequest: DtoCreateTaintRequest;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,16 +12,42 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
import type { DtoDomainResponse } from "./DtoDomainResponse";
|
import type { DtoDomainResponse } from "./DtoDomainResponse";
|
||||||
import {DtoDomainResponseFromJSON, DtoDomainResponseToJSON,} from "./DtoDomainResponse";
|
import {
|
||||||
|
DtoDomainResponseFromJSON,
|
||||||
|
DtoDomainResponseFromJSONTyped,
|
||||||
|
DtoDomainResponseToJSON,
|
||||||
|
DtoDomainResponseToJSONTyped,
|
||||||
|
} from "./DtoDomainResponse";
|
||||||
import type { DtoLoadBalancerResponse } from "./DtoLoadBalancerResponse";
|
import type { DtoLoadBalancerResponse } from "./DtoLoadBalancerResponse";
|
||||||
import {DtoLoadBalancerResponseFromJSON, DtoLoadBalancerResponseToJSON,} from "./DtoLoadBalancerResponse";
|
import {
|
||||||
|
DtoLoadBalancerResponseFromJSON,
|
||||||
|
DtoLoadBalancerResponseFromJSONTyped,
|
||||||
|
DtoLoadBalancerResponseToJSON,
|
||||||
|
DtoLoadBalancerResponseToJSONTyped,
|
||||||
|
} from "./DtoLoadBalancerResponse";
|
||||||
import type { DtoNodePoolResponse } from "./DtoNodePoolResponse";
|
import type { DtoNodePoolResponse } from "./DtoNodePoolResponse";
|
||||||
import {DtoNodePoolResponseFromJSON, DtoNodePoolResponseToJSON,} from "./DtoNodePoolResponse";
|
import {
|
||||||
|
DtoNodePoolResponseFromJSON,
|
||||||
|
DtoNodePoolResponseFromJSONTyped,
|
||||||
|
DtoNodePoolResponseToJSON,
|
||||||
|
DtoNodePoolResponseToJSONTyped,
|
||||||
|
} from "./DtoNodePoolResponse";
|
||||||
import type { DtoServerResponse } from "./DtoServerResponse";
|
import type { DtoServerResponse } from "./DtoServerResponse";
|
||||||
import {DtoServerResponseFromJSON, DtoServerResponseToJSON,} from "./DtoServerResponse";
|
import {
|
||||||
|
DtoServerResponseFromJSON,
|
||||||
|
DtoServerResponseFromJSONTyped,
|
||||||
|
DtoServerResponseToJSON,
|
||||||
|
DtoServerResponseToJSONTyped,
|
||||||
|
} from "./DtoServerResponse";
|
||||||
import type { DtoRecordSetResponse } from "./DtoRecordSetResponse";
|
import type { DtoRecordSetResponse } from "./DtoRecordSetResponse";
|
||||||
import {DtoRecordSetResponseFromJSON, DtoRecordSetResponseToJSON,} from "./DtoRecordSetResponse";
|
import {
|
||||||
|
DtoRecordSetResponseFromJSON,
|
||||||
|
DtoRecordSetResponseFromJSONTyped,
|
||||||
|
DtoRecordSetResponseToJSON,
|
||||||
|
DtoRecordSetResponseToJSONTyped,
|
||||||
|
} from "./DtoRecordSetResponse";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -77,6 +103,18 @@ export interface DtoClusterResponse {
|
|||||||
* @memberof DtoClusterResponse
|
* @memberof DtoClusterResponse
|
||||||
*/
|
*/
|
||||||
created_at?: string;
|
created_at?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof DtoClusterResponse
|
||||||
|
*/
|
||||||
|
docker_image?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof DtoClusterResponse
|
||||||
|
*/
|
||||||
|
docker_tag?: string;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {DtoLoadBalancerResponse}
|
* @type {DtoLoadBalancerResponse}
|
||||||
@@ -179,6 +217,9 @@ export function DtoClusterResponseFromJSONTyped(
|
|||||||
? undefined
|
? undefined
|
||||||
: DtoRecordSetResponseFromJSON(json["control_plane_record_set"]),
|
: DtoRecordSetResponseFromJSON(json["control_plane_record_set"]),
|
||||||
created_at: json["created_at"] == null ? undefined : json["created_at"],
|
created_at: json["created_at"] == null ? undefined : json["created_at"],
|
||||||
|
docker_image:
|
||||||
|
json["docker_image"] == null ? undefined : json["docker_image"],
|
||||||
|
docker_tag: json["docker_tag"] == null ? undefined : json["docker_tag"],
|
||||||
glueops_load_balancer:
|
glueops_load_balancer:
|
||||||
json["glueops_load_balancer"] == null
|
json["glueops_load_balancer"] == null
|
||||||
? undefined
|
? undefined
|
||||||
@@ -223,6 +264,8 @@ export function DtoClusterResponseToJSONTyped(
|
|||||||
value["control_plane_record_set"],
|
value["control_plane_record_set"],
|
||||||
),
|
),
|
||||||
created_at: value["created_at"],
|
created_at: value["created_at"],
|
||||||
|
docker_image: value["docker_image"],
|
||||||
|
docker_tag: value["docker_tag"],
|
||||||
glueops_load_balancer: DtoLoadBalancerResponseToJSON(
|
glueops_load_balancer: DtoLoadBalancerResponseToJSON(
|
||||||
value["glueops_load_balancer"],
|
value["glueops_load_balancer"],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
@@ -24,6 +25,18 @@ export interface DtoCreateClusterRequest {
|
|||||||
* @memberof DtoCreateClusterRequest
|
* @memberof DtoCreateClusterRequest
|
||||||
*/
|
*/
|
||||||
cluster_provider?: string;
|
cluster_provider?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof DtoCreateClusterRequest
|
||||||
|
*/
|
||||||
|
docker_image?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof DtoCreateClusterRequest
|
||||||
|
*/
|
||||||
|
docker_tag?: string;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@@ -63,6 +76,9 @@ export function DtoCreateClusterRequestFromJSONTyped(
|
|||||||
return {
|
return {
|
||||||
cluster_provider:
|
cluster_provider:
|
||||||
json["cluster_provider"] == null ? undefined : json["cluster_provider"],
|
json["cluster_provider"] == null ? undefined : json["cluster_provider"],
|
||||||
|
docker_image:
|
||||||
|
json["docker_image"] == null ? undefined : json["docker_image"],
|
||||||
|
docker_tag: json["docker_tag"] == null ? undefined : json["docker_tag"],
|
||||||
name: json["name"] == null ? undefined : json["name"],
|
name: json["name"] == null ? undefined : json["name"],
|
||||||
region: json["region"] == null ? undefined : json["region"],
|
region: json["region"] == null ? undefined : json["region"],
|
||||||
};
|
};
|
||||||
@@ -84,6 +100,8 @@ export function DtoCreateClusterRequestToJSONTyped(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
cluster_provider: value["cluster_provider"],
|
cluster_provider: value["cluster_provider"],
|
||||||
|
docker_image: value["docker_image"],
|
||||||
|
docker_tag: value["docker_tag"],
|
||||||
name: value["name"],
|
name: value["name"],
|
||||||
region: value["region"],
|
region: value["region"],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,8 +12,14 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
import type { DtoJWK } from "./DtoJWK";
|
import type { DtoJWK } from "./DtoJWK";
|
||||||
import {DtoJWKFromJSON, DtoJWKToJSON,} from "./DtoJWK";
|
import {
|
||||||
|
DtoJWKFromJSON,
|
||||||
|
DtoJWKFromJSONTyped,
|
||||||
|
DtoJWKToJSON,
|
||||||
|
DtoJWKToJSONTyped,
|
||||||
|
} from "./DtoJWK";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,8 +12,14 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
import type { DtoJobStatus } from "./DtoJobStatus";
|
import type { DtoJobStatus } from "./DtoJobStatus";
|
||||||
import {DtoJobStatusFromJSON, DtoJobStatusToJSON,} from "./DtoJobStatus";
|
import {
|
||||||
|
DtoJobStatusFromJSON,
|
||||||
|
DtoJobStatusFromJSONTyped,
|
||||||
|
DtoJobStatusToJSON,
|
||||||
|
DtoJobStatusToJSONTyped,
|
||||||
|
} from "./DtoJobStatus";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,14 +12,35 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
import type { DtoTaintResponse } from "./DtoTaintResponse";
|
import type { DtoTaintResponse } from "./DtoTaintResponse";
|
||||||
import {DtoTaintResponseFromJSON, DtoTaintResponseToJSON,} from "./DtoTaintResponse";
|
import {
|
||||||
|
DtoTaintResponseFromJSON,
|
||||||
|
DtoTaintResponseFromJSONTyped,
|
||||||
|
DtoTaintResponseToJSON,
|
||||||
|
DtoTaintResponseToJSONTyped,
|
||||||
|
} from "./DtoTaintResponse";
|
||||||
import type { DtoLabelResponse } from "./DtoLabelResponse";
|
import type { DtoLabelResponse } from "./DtoLabelResponse";
|
||||||
import {DtoLabelResponseFromJSON, DtoLabelResponseToJSON,} from "./DtoLabelResponse";
|
import {
|
||||||
|
DtoLabelResponseFromJSON,
|
||||||
|
DtoLabelResponseFromJSONTyped,
|
||||||
|
DtoLabelResponseToJSON,
|
||||||
|
DtoLabelResponseToJSONTyped,
|
||||||
|
} from "./DtoLabelResponse";
|
||||||
import type { DtoServerResponse } from "./DtoServerResponse";
|
import type { DtoServerResponse } from "./DtoServerResponse";
|
||||||
import {DtoServerResponseFromJSON, DtoServerResponseToJSON,} from "./DtoServerResponse";
|
import {
|
||||||
|
DtoServerResponseFromJSON,
|
||||||
|
DtoServerResponseFromJSONTyped,
|
||||||
|
DtoServerResponseToJSON,
|
||||||
|
DtoServerResponseToJSONTyped,
|
||||||
|
} from "./DtoServerResponse";
|
||||||
import type { DtoAnnotationResponse } from "./DtoAnnotationResponse";
|
import type { DtoAnnotationResponse } from "./DtoAnnotationResponse";
|
||||||
import {DtoAnnotationResponseFromJSON, DtoAnnotationResponseToJSON,} from "./DtoAnnotationResponse";
|
import {
|
||||||
|
DtoAnnotationResponseFromJSON,
|
||||||
|
DtoAnnotationResponseFromJSONTyped,
|
||||||
|
DtoAnnotationResponseToJSON,
|
||||||
|
DtoAnnotationResponseToJSONTyped,
|
||||||
|
} from "./DtoAnnotationResponse";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,8 +12,14 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
import type { DtoJob } from "./DtoJob";
|
import type { DtoJob } from "./DtoJob";
|
||||||
import {DtoJobFromJSON, DtoJobToJSON,} from "./DtoJob";
|
import {
|
||||||
|
DtoJobFromJSON,
|
||||||
|
DtoJobFromJSONTyped,
|
||||||
|
DtoJobToJSON,
|
||||||
|
DtoJobToJSONTyped,
|
||||||
|
} from "./DtoJob";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from "../runtime";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user