Skip to content

Commit

Permalink
feat: show deployment target status (#46)
Browse files Browse the repository at this point in the history
Signed-off-by: christoph <christoph.enne@glasskube.eu>
  • Loading branch information
christophenne authored Nov 28, 2024
1 parent a605e39 commit 79cb6fa
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
</th>
-->
<th scope="col" class="p-4">Deployment Target</th>
<th scope="col" class="p-4">Status</th>
<th scope="col" class="p-4">Type</th>
@if (fullVersion) {
<th scope="col" class="p-4">Creation Date</th>
Expand All @@ -97,10 +98,28 @@
-->
<th scope="row" class="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">
<div class="flex items-center mr-3">
<img ngSrc="/docker.png" alt="Docker" class="h-8 w-auto mr-3 rounded" height="199" width="199" />
<div class="relative mr-3">
<img ngSrc="/docker.png" alt="Docker" class="h-8 w-auto rounded" height="199" width="199" />
@if (dt.currentStatus) {
<span class="absolute w-2 h-2 rounded bg-lime-700 -bottom-0.5 -end-0.5"></span>
} @else {
<span class="absolute w-2 h-2 rounded bg-gray-500 -bottom-0.5 -end-0.5"></span>
}
</div>
{{ dt.name }}
</div>
</th>
<td class="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">
<div class="flex items-center">
@if (dt.currentStatus) {
<div class="h-4 w-4 rounded-full inline-block mr-2 bg-lime-700"></div>
OK
} @else {
<div class="h-4 w-4 rounded-full inline-block mr-2 bg-gray-500"></div>
Unknown
}
</div>
</td>
<td class="px-4 py-3">
<span
class="bg-blue-100 text-blue-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded dark:bg-blue-900 dark:text-blue-300">
Expand Down
5 changes: 5 additions & 0 deletions frontend/cloud-ui/src/app/types/deployment-target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ export interface DeploymentTarget extends BaseModel, Named {
name: string;
type: string;
geolocation?: Geolocation;
currentStatus?: DeploymentTargetStatus;
}

export interface DeploymentTargetStatus extends BaseModel {
message: string;
}
32 changes: 23 additions & 9 deletions internal/db/deployment_targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,28 @@ import (

const (
deploymentTargetOutputExpr = `
id, created_at, name, type,
CASE WHEN geolocation_lat IS NOT NULL AND geolocation_lon IS NOT NULL
THEN (geolocation_lat, geolocation_lon) END AS geolocation
dt.id, dt.created_at, dt.name, dt.type,
CASE WHEN dt.geolocation_lat IS NOT NULL AND dt.geolocation_lon IS NOT NULL
THEN (dt.geolocation_lat, dt.geolocation_lon) END AS geolocation
`
deploymentTargetWithStatusOutputExpr = deploymentTargetOutputExpr + `,
CASE WHEN status.id IS NOT NULL
THEN (status.id, status.created_at, status.message) END AS current_status
`
deploymentTargetFromExpr = `
FROM DeploymentTarget dt LEFT JOIN DeploymentTargetStatus status ON dt.id = status.deployment_target_id
WHERE (
status.id IS NULL OR status.created_at = (
SELECT max(s.created_at) FROM DeploymentTargetStatus s WHERE s.deployment_target_id = status.deployment_target_id
)
)
`
)

func GetDeploymentTargets(ctx context.Context) ([]types.DeploymentTarget, error) {
db := internalctx.GetDb(ctx)
if rows, err := db.Query(ctx, "SELECT "+deploymentTargetOutputExpr+" FROM DeploymentTarget"); err != nil {
if rows, err := db.Query(ctx,
"SELECT "+deploymentTargetWithStatusOutputExpr+" "+deploymentTargetFromExpr); err != nil {
return nil, fmt.Errorf("failed to query DeploymentTargets: %w", err)
} else if result, err := pgx.CollectRows(rows, pgx.RowToStructByName[types.DeploymentTarget]); err != nil {
return nil, fmt.Errorf("failed to get DeploymentTargets: %w", err)
Expand All @@ -34,7 +47,7 @@ func GetDeploymentTargets(ctx context.Context) ([]types.DeploymentTarget, error)
func GetDeploymentTarget(ctx context.Context, id string) (*types.DeploymentTarget, error) {
db := internalctx.GetDb(ctx)
rows, err := db.Query(ctx,
"SELECT "+deploymentTargetOutputExpr+" FROM DeploymentTarget WHERE id = @id",
"SELECT "+deploymentTargetWithStatusOutputExpr+" "+deploymentTargetFromExpr+" AND dt.id = @id",
pgx.NamedArgs{"id": id})
if err != nil {
return nil, fmt.Errorf("failed to query DeploymentTargets: %w", err)
Expand All @@ -56,14 +69,14 @@ func CreateDeploymentTarget(ctx context.Context, dt *types.DeploymentTarget) err
maps.Copy(args, pgx.NamedArgs{"lat": dt.Geolocation.Lat, "lon": dt.Geolocation.Lon})
}
rows, err := db.Query(ctx,
"INSERT INTO DeploymentTarget (name, type, geolocation_lat, geolocation_lon) "+
"INSERT INTO DeploymentTarget AS dt (name, type, geolocation_lat, geolocation_lon) "+
"VALUES (@name, @type, @lat, @lon) RETURNING "+
deploymentTargetOutputExpr,
args)
if err != nil {
return fmt.Errorf("failed to query DeploymentTargets: %w", err)
}
result, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[types.DeploymentTarget])
result, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByNameLax[types.DeploymentTarget])
if err != nil {
return fmt.Errorf("could not save DeploymentTarget: %w", err)
} else {
Expand All @@ -79,13 +92,14 @@ func UpdateDeploymentTarget(ctx context.Context, dt *types.DeploymentTarget) err
maps.Copy(args, pgx.NamedArgs{"lat": dt.Geolocation.Lat, "lon": dt.Geolocation.Lon})
}
rows, err := db.Query(ctx,
"UPDATE DeploymentTarget SET name = @name, geolocation_lat = @lat, geolocation_lon = @lon "+
"UPDATE DeploymentTarget AS dt SET name = @name, geolocation_lat = @lat, geolocation_lon = @lon "+
" WHERE id = @id RETURNING "+
deploymentTargetOutputExpr,
args)
if err != nil {
return fmt.Errorf("could not update DeploymentTarget: %w", err)
} else if updated, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[types.DeploymentTarget]); err != nil {
} else if updated, err :=
pgx.CollectExactlyOneRow(rows, pgx.RowToStructByNameLax[types.DeploymentTarget]); err != nil {
return fmt.Errorf("could not get updated DeploymentTarget: %w", err)
} else {
*dt = updated
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/deployment_targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func deploymentTargetMiddelware(wh http.Handler) http.Handler {
if errors.Is(err, apierrors.NotFound) {
w.WriteHeader(http.StatusNotFound)
} else if err != nil {
internalctx.GetLogger(r.Context()).Error("failed to get application", zap.Error(err))
internalctx.GetLogger(r.Context()).Error("failed to get DeploymentTarget", zap.Error(err))
w.WriteHeader(http.StatusInternalServerError)
} else {
ctx = internalctx.WithDeploymentTarget(ctx, deploymentTarget)
Expand Down
17 changes: 13 additions & 4 deletions internal/types/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Application struct {
}

type ApplicationVersion struct {
// unfortunately Base nested type doesn't work when ApplicationVersion is a nested row in an SQL query
// TODO unfortunately Base nested type doesn't work when ApplicationVersion is a nested row in an SQL query
ID string `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"createdAt"`
Name string `db:"name" json:"name"`
Expand All @@ -20,7 +20,16 @@ type ApplicationVersion struct {

type DeploymentTarget struct {
Base
Name string `db:"name" json:"name"`
Type DeploymentType `db:"type" json:"type"`
Geolocation *Geolocation `db:"geolocation" json:"geolocation,omitempty"`
Name string `db:"name" json:"name"`
Type DeploymentType `db:"type" json:"type"`
Geolocation *Geolocation `db:"geolocation" json:"geolocation,omitempty"`
CurrentStatus *DeploymentTargetStatus `db:"current_status" json:"currentStatus,omitempty"`
}

type DeploymentTargetStatus struct {
// TODO unfortunately Base nested type doesn't work when ApplicationVersion is a nested row in an SQL query
ID string `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"createdAt"`
Message string `db:"message" json:"message"`
DeploymentTargetId string `db:"deployment_target_id" json:"-"`
}

0 comments on commit 79cb6fa

Please sign in to comment.