Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/dashboard/lib/audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ export type UnkeyAuditLog = {
| "secret"
| "project"
| "identity"
| "auditLogBucket";
| "auditLogBucket"
| "environment";

id: string;
name?: string;
Expand Down
31 changes: 30 additions & 1 deletion apps/dashboard/lib/trpc/routers/deploy/project/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export const createProject = t.procedure
await tx.insert(schema.projects).values({
id: projectId,
workspaceId,
partitionId: "part_default", // Default partition for now
name: input.name,
slug: input.slug,
gitRepositoryUrl: input.gitRepositoryUrl || null,
Expand All @@ -95,6 +94,36 @@ export const createProject = t.procedure
userAgent: ctx.audit.userAgent,
},
});

for (const slug of ["production", "preview"]) {
const environmentId = newId("environment");
await tx.insert(schema.environments).values({
id: environmentId,
workspaceId,
projectId,
slug: slug,
});
await insertAuditLogs(tx, {
workspaceId,
actor: {
type: "user",
id: userId,
},
event: "environment.create",
description: `Created environment "${slug}" for project "${input.name}"`,
resources: [
{
type: "environment",
id: environmentId,
name: slug,
},
],
context: {
location: ctx.audit.location,
userAgent: ctx.audit.userAgent,
},
});
}
});
} catch (txErr) {
console.error({
Expand Down
34 changes: 20 additions & 14 deletions apps/dashboard/lib/trpc/routers/deploy/project/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ export const queryProjects = t.procedure
queryConditions.push(
exists(
db
.select({ projectId: schema.routes.projectId })
.from(schema.routes)
.select({ projectId: schema.domains.projectId })
.from(schema.domains)
.where(
and(
eq(schema.routes.workspaceId, ctx.workspace.id),
eq(schema.routes.projectId, schema.projects.id),
like(schema.routes.hostname, searchValue),
eq(schema.domains.workspaceId, ctx.workspace.id),
eq(schema.domains.projectId, schema.projects.id),
like(schema.domains.domain, searchValue),
),
),
),
Expand Down Expand Up @@ -165,16 +165,16 @@ export const queryProjects = t.procedure
// Fetch hostnames for all projects - only .unkey.app domains
const hostnamesResult =
projectIds.length > 0
? await db.query.routes.findMany({
? await db.query.domains.findMany({
where: and(
eq(schema.routes.workspaceId, ctx.workspace.id),
inArray(schema.routes.projectId, projectIds),
like(schema.routes.hostname, "%.unkey.app"),
eq(schema.domains.workspaceId, ctx.workspace.id),
inArray(schema.domains.projectId, projectIds),
like(schema.domains.domain, "%.unkey.app"),
),
columns: {
id: true,
projectId: true,
hostname: true,
domain: true,
},
orderBy: [desc(schema.projects.updatedAt), desc(schema.projects.createdAt)],
})
Expand All @@ -183,12 +183,18 @@ export const queryProjects = t.procedure
// Group hostnames by projectId
const hostnamesByProject = hostnamesResult.reduce(
(acc, hostname) => {
if (!acc[hostname.projectId]) {
acc[hostname.projectId] = [];
// Make typescript happy, we already ensure this is the case in the drizzle query
const projectId = hostname.projectId;
if (!projectId) {
return acc;
}
acc[hostname.projectId].push({

if (!acc[projectId]) {
acc[projectId] = [];
}
acc[projectId].push({
id: hostname.id,
hostname: hostname.hostname,
hostname: hostname.domain,
});
return acc;
},
Expand Down
5 changes: 4 additions & 1 deletion apps/dashboard/lib/trpc/routers/deployment/getById.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export const getById = t.procedure
try {
// Get deployment information
const deployment = await db.query.deployments.findFirst({
with: {
environment: { columns: { slug: true } },
},
where: (table, { eq, and }) =>
and(eq(table.id, input.deploymentId), eq(table.workspaceId, ctx.workspace.id)),
});
Expand All @@ -31,7 +34,7 @@ export const getById = t.procedure
status: deployment.status,
gitCommitSha: deployment.gitCommitSha,
gitBranch: deployment.gitBranch,
environment: deployment.environment,
environment: deployment.environment?.slug ?? "",
createdAt: deployment.createdAt,
updatedAt: deployment.updatedAt,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export const getOpenApiDiff = t.procedure
openapiSpec: true,
gitCommitSha: true,
gitBranch: true,
environment: true,
// TODO: add this column
//gitCommitMessage: true,
},
with: {
environment: true,
project: {
columns: {
id: true,
Expand All @@ -47,10 +47,10 @@ export const getOpenApiDiff = t.procedure
openapiSpec: true,
gitCommitSha: true,
gitBranch: true,
environment: true,
//gitCommitMessage: true,
},
with: {
environment: true,
project: {
columns: {
id: true,
Expand Down
7 changes: 3 additions & 4 deletions apps/dashboard/lib/trpc/routers/deployment/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export const listDeployments = t.procedure
where: (table, { eq }) => eq(table.workspaceId, ctx.workspace.id),
orderBy: (table, { desc }) => [desc(table.createdAt)],
with: {
project: true,
environment: { columns: { slug: true } },
project: { columns: { id: true, name: true, slug: true } },
},
});

Expand All @@ -22,9 +23,7 @@ export const listDeployments = t.procedure
status: deployment.status,
gitCommitSha: deployment.gitCommitSha,
gitBranch: deployment.gitBranch,
environment: deployment.environment,
rootfsImageId: deployment.rootfsImageId,
buildId: deployment.buildId,
environment: deployment.environment.slug,
createdAt: deployment.createdAt,
updatedAt: deployment.updatedAt,
project: deployment.project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const listByEnvironment = t.procedure
.input(
z.object({
projectId: z.string(),
environment: z.enum(["production", "preview"]),
environmentId: z.string(),
}),
)
.query(async ({ input, ctx }) => {
Expand All @@ -30,7 +30,7 @@ export const listByEnvironment = t.procedure
// Get all deployments for this project and environment
const deployments = await db.query.deployments.findMany({
where: (table, { eq, and }) =>
and(eq(table.projectId, input.projectId), eq(table.environment, input.environment)),
and(eq(table.projectId, input.projectId), eq(table.environmentId, input.environmentId)),
orderBy: (table, { desc }) => [desc(table.createdAt)],
});

Expand Down
7 changes: 3 additions & 4 deletions apps/dashboard/lib/trpc/routers/deployment/listByProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export const listByProject = t.procedure
where: (table, { eq }) => eq(table.projectId, input.projectId),
orderBy: (table, { desc }) => [desc(table.createdAt)],
with: {
project: true,
environment: { columns: { slug: true } },
project: { columns: { id: true, name: true, slug: true } },
},
});

Expand All @@ -49,9 +50,7 @@ export const listByProject = t.procedure
status: deployment.status,
gitCommitSha: deployment.gitCommitSha,
gitBranch: deployment.gitBranch,
environment: deployment.environment,
rootfsImageId: deployment.rootfsImageId,
buildId: deployment.buildId,
environment: deployment.environment.slug,
createdAt: deployment.createdAt,
updatedAt: deployment.updatedAt,
project: deployment.project
Expand Down
6 changes: 6 additions & 0 deletions deployment/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ services:
- mysql
- metald-aio
- otel
- s3
environment:
# Database configuration - use existing mysql service
UNKEY_DATABASE_PRIMARY: "unkey:password@tcp(mysql:3306)/unkey?parseTime=true"
Expand All @@ -236,6 +237,11 @@ services:
# Control plane configuration
UNKEY_HTTP_PORT: "7091"
UNKEY_METALD_ADDRESS: "http://metald-aio:8080"
UNKEY_VAULT_S3_URL: "http://s3:3902"
UNKEY_VAULT_S3_BUCKET: "vault"
UNKEY_VAULT_S3_ACCESS_KEY_ID: "minio_root_user"
UNKEY_VAULT_S3_ACCESS_KEY_SECRET: "minio_root_password"
UNKEY_VAULT_MASTER_KEYS: "Ch9rZWtfMmdqMFBJdVhac1NSa0ZhNE5mOWlLSnBHenFPENTt7an5MRogENt9Si6wms4pQ2XIvqNSIgNpaBenJmXgcInhu6Nfv2U="
otel:
image: grafana/otel-lgtm:0.11.7
container_name: otel
Expand Down
24 changes: 10 additions & 14 deletions go/apps/ctrl/config.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package ctrl

import (
"github.com/unkeyed/unkey/go/pkg/assert"
"github.com/unkeyed/unkey/go/pkg/clock"
"github.com/unkeyed/unkey/go/pkg/tls"
"github.com/unkeyed/unkey/go/pkg/vault/storage"
)

type S3Config struct {
URL string
Bucket string
AccessKeyID string
AccessKeySecret string
}

type Config struct {
// InstanceID is the unique identifier for this instance of the control plane server
InstanceID string
Expand Down Expand Up @@ -52,21 +57,12 @@ type Config struct {

// --- Vault Configuration ---
VaultMasterKeys []string
VaultS3 *storage.S3Config
VaultS3 S3Config

AcmeEnabled bool
}

func (c Config) Validate() error {
if c.VaultS3 != nil {
err := assert.All(
assert.NotEmpty(c.VaultS3.S3URL, "vault s3 url is empty"),
assert.NotEmpty(c.VaultS3.S3Bucket, "vault s3 bucket is empty"),
assert.NotEmpty(c.VaultS3.S3AccessKeyID, "vault s3 access key id is empty"),
assert.NotEmpty(c.VaultS3.S3AccessKeySecret, "vault s3 secret access key is empty"),
)
if err != nil {
return err
}
}

return nil
}
Loading