diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index aee0753..72ebede 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,9 @@ { "name": "Crucible Development", + "runArgs": [ + "--name", + "crucible-dev" + ], "build": { "dockerfile": "Dockerfile" }, diff --git a/.env/alloy.env b/.env/alloy.env new file mode 100644 index 0000000..a1376c2 --- /dev/null +++ b/.env/alloy.env @@ -0,0 +1,8 @@ +Launch__Player=false +Launch__Caster=false +Launch__Alloy=true +Launch__TopoMojo=false +Launch__Steamfitter=false +Launch__Cite=false +Launch__Gallery=false +Launch__Blueprint=false diff --git a/.env/caster.env b/.env/caster.env new file mode 100644 index 0000000..f2cd149 --- /dev/null +++ b/.env/caster.env @@ -0,0 +1,8 @@ +Launch__Player=false +Launch__Caster=true +Launch__Alloy=false +Launch__TopoMojo=false +Launch__Steamfitter=false +Launch__Cite=false +Launch__Gallery=false +Launch__Blueprint=false diff --git a/.env/player.env b/.env/player.env new file mode 100644 index 0000000..3de9697 --- /dev/null +++ b/.env/player.env @@ -0,0 +1,8 @@ +Launch__Player=true +Launch__Caster=false +Launch__Alloy=false +Launch__TopoMojo=false +Launch__Steamfitter=false +Launch__Cite=false +Launch__Gallery=false +Launch__Blueprint=false diff --git a/.env/steamfitter.env b/.env/steamfitter.env new file mode 100644 index 0000000..0f6653f --- /dev/null +++ b/.env/steamfitter.env @@ -0,0 +1,8 @@ +Launch__Player=false +Launch__Caster=false +Launch__Alloy=false +Launch__TopoMojo=false +Launch__Steamfitter=true +Launch__Cite=false +Launch__Gallery=false +Launch__Blueprint=false diff --git a/.gitignore b/.gitignore index 648f630..8485a33 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ nunit-*.xml # devcontainer certs .devcontainer/certs/*.crt + +# db dumps to restore into postgres +db-dumps/ \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 031b703..5496c02 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,6 +18,62 @@ "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", "envFile": "${workspaceFolder}/.env/exercise.env" }, + { + "name": "TTX", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", + "envFile": "${workspaceFolder}/.env/ttx.env" + }, + { + "name": "Alloy", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", + "envFile": "${workspaceFolder}/.env/alloy.env" + }, + { + "name": "Blueprint", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", + "envFile": "${workspaceFolder}/.env/blueprint.env" + }, + { + "name": "Caster", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", + "envFile": "${workspaceFolder}/.env/caster.env" + }, + { + "name": "CITE", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", + "envFile": "${workspaceFolder}/.env/cite.env" + }, + { + "name": "Gallery", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", + "envFile": "${workspaceFolder}/.env/gallery.env" + }, + { + "name": "Player", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", + "envFile": "${workspaceFolder}/.env/player.env" + }, + { + "name": "Steamfitter", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Crucible.Apphost/Crucible.AppHost.csproj", + "envFile": "${workspaceFolder}/.env/steamfitter.env" + }, { "name": "TopoMojo", "type": "dotnet", @@ -26,4 +82,4 @@ "envFile": "${workspaceFolder}/.env/topo.env" } ] -} \ No newline at end of file +} diff --git a/Crucible.AppHost/AppHost.cs b/Crucible.AppHost/AppHost.cs index e7aa363..c7838ff 100644 --- a/Crucible.AppHost/AppHost.cs +++ b/Crucible.AppHost/AppHost.cs @@ -13,10 +13,17 @@ var postgres = builder.AddPostgres("postgres") .WithDataVolume() .WithLifetime(ContainerLifetime.Persistent) + .WithContainerName("crucible-postgres") .WithPgAdmin(); +var keycloakDb = postgres.AddDatabase("keycloakDb", "keycloak"); var keycloak = builder.AddKeycloak("keycloak", 8080) - .WithLifetime(ContainerLifetime.Persistent) + .WithReference(keycloakDb) + // Configure environment variables for the PostgreSQL connection + .WithEnvironment("KC_DB", "postgres") + .WithEnvironment("KC_DB_URL_HOST", postgres.Resource.PrimaryEndpoint.Property(EndpointProperty.Host)) + .WithEnvironment("KC_DB_USERNAME", postgres.Resource.UserNameReference) + .WithEnvironment("KC_DB_PASSWORD", postgres.Resource.PasswordParameter) .WithRealmImport($"{builder.AppHostDirectory}/resources/crucible-realm.json"); var mkdocs = builder.AddContainer("mkdocs", "squidfunk/mkdocs-material") @@ -49,6 +56,7 @@ public static void AddPlayer(this IDistributedApplicationBuilder builder, IResou .WithHttpHealthCheck("api/health/ready") .WithReference(playerDb, "PostgreSQL") .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("Authorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("Authorization__AuthorizationUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/auth") .WithEnvironment("Authorization__TokenUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/token") @@ -76,6 +84,7 @@ private static void AddPlayerVm(this IDistributedApplicationBuilder builder, IRe .WithHttpHealthCheck("api/health/ready") .WithReference(vmDb, "PostgreSQL") .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("VmUsageLogging__Enabled", "true") .WithEnvironment("VmUsageLogging__PostgreSQL", vmLoggingDb.Resource.ConnectionStringExpression) .WithEnvironment("Authorization__Authority", "http://localhost:8080/realms/crucible") @@ -112,6 +121,7 @@ public static void AddCaster(this IDistributedApplicationBuilder builder, IResou .WithHttpHealthCheck("api/health/ready") .WithReference(casterDb, "PostgreSQL") .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("Authorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("Authorization__AuthorizationUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/auth") .WithEnvironment("Authorization__TokenUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/token") @@ -138,6 +148,7 @@ public static void AddAlloy(this IDistributedApplicationBuilder builder, IResour .WithHttpHealthCheck("api/health/ready") .WithReference(alloyDb, "PostgreSQL") .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("Authorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("Authorization__AuthorizationUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/auth") .WithEnvironment("Authorization__TokenUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/token") @@ -172,6 +183,7 @@ public static void AddTopoMojo(this IDistributedApplicationBuilder builder, IRes .WithReference(topoDb, "PostgreSQL") .WithEnvironment("Database__ConnectionString", topoDb.Resource.ConnectionStringExpression) .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("Oidc__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("Oidc__Audience", "topomojo") .WithEnvironment("OpenApi__Client__AuthorizationUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/auth") @@ -209,15 +221,17 @@ public static void AddSteamfitter(this IDistributedApplicationBuilder builder, I .WithHttpHealthCheck("api/health/ready") .WithReference(steamfitterDb, "PostgreSQL") .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("Authorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("Authorization__AuthorizationUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/auth") .WithEnvironment("Authorization__TokenUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/token") + .WithEnvironment("Authorization__AuthorizationScope", "steamfitter player player-vm") .WithEnvironment("Authorization__ClientId", "steamfitter.api") .WithEnvironment("ResourceOwnerAuthorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("ResourceOwnerAuthorization__ClientId", "steamfitter.admin") .WithEnvironment("ResourceOwnerAuthorization__UserName", "admin") .WithEnvironment("ResourceOwnerAuthorization__Password", "admin") - .WithEnvironment("ResourceOwnerAuthorization__Scope", "player player-vm alloy steamfitter caster") + .WithEnvironment("ResourceOwnerAuthorization__Scope", "steamfitter player player-vm cite gallery") .WithEnvironment("ResourceOwnerAuthorization__ValidateDiscoveryDocument", "false"); var steamfitterUiRoot = "/mnt/data/crucible/steamfitter/steamfitter.ui"; @@ -241,15 +255,17 @@ public static void AddCite(this IDistributedApplicationBuilder builder, IResourc .WithHttpHealthCheck("api/health/ready") .WithReference(citeDb, "PostgreSQL") .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("Authorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("Authorization__AuthorizationUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/auth") .WithEnvironment("Authorization__TokenUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/token") + .WithEnvironment("Authorization__AuthorizationScope", "cite") .WithEnvironment("Authorization__ClientId", "cite.api") .WithEnvironment("ResourceOwnerAuthorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("ResourceOwnerAuthorization__ClientId", "cite.admin") .WithEnvironment("ResourceOwnerAuthorization__UserName", "admin") .WithEnvironment("ResourceOwnerAuthorization__Password", "admin") - .WithEnvironment("ResourceOwnerAuthorization__Scope", "player player-vm cite steamfitter caster") + .WithEnvironment("ResourceOwnerAuthorization__Scope", "openid profile email cite gallery") .WithEnvironment("ResourceOwnerAuthorization__ValidateDiscoveryDocument", "false"); var citeUiRoot = "/mnt/data/crucible/cite/cite.ui"; @@ -273,15 +289,17 @@ public static void AddGallery(this IDistributedApplicationBuilder builder, IReso .WithHttpHealthCheck("api/health/ready") .WithReference(galleryDb, "PostgreSQL") .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("Authorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("Authorization__AuthorizationUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/auth") .WithEnvironment("Authorization__TokenUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/token") + .WithEnvironment("Authorization__AuthorizationScope", "gallery") .WithEnvironment("Authorization__ClientId", "gallery.api") .WithEnvironment("ResourceOwnerAuthorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("ResourceOwnerAuthorization__ClientId", "gallery.admin") .WithEnvironment("ResourceOwnerAuthorization__UserName", "admin") .WithEnvironment("ResourceOwnerAuthorization__Password", "admin") - .WithEnvironment("ResourceOwnerAuthorization__Scope", "player player-vm gallery steamfitter caster") + .WithEnvironment("ResourceOwnerAuthorization__Scope", "player player-vm steamfitter") .WithEnvironment("ResourceOwnerAuthorization__ValidateDiscoveryDocument", "false"); var galleryUiRoot = "/mnt/data/crucible/gallery/gallery.ui"; @@ -305,6 +323,7 @@ public static void AddBlueprint(this IDistributedApplicationBuilder builder, IRe .WithHttpHealthCheck("api/health/ready") .WithReference(blueprintDb, "PostgreSQL") .WithEnvironment("Database__Provider", "PostgreSQL") + .WithEnvironment("Database__DevModeRecreate", "false") .WithEnvironment("Authorization__Authority", "http://localhost:8080/realms/crucible") .WithEnvironment("Authorization__AuthorizationUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/auth") .WithEnvironment("Authorization__TokenUrl", "http://localhost:8080/realms/crucible/protocol/openid-connect/token") @@ -313,7 +332,7 @@ public static void AddBlueprint(this IDistributedApplicationBuilder builder, IRe .WithEnvironment("ResourceOwnerAuthorization__ClientId", "blueprint.admin") .WithEnvironment("ResourceOwnerAuthorization__UserName", "admin") .WithEnvironment("ResourceOwnerAuthorization__Password", "admin") - .WithEnvironment("ResourceOwnerAuthorization__Scope", "player player-vm blueprint steamfitter caster") + .WithEnvironment("ResourceOwnerAuthorization__Scope", "player player-vm gallery steamfitter cite") .WithEnvironment("ResourceOwnerAuthorization__ValidateDiscoveryDocument", "false"); var blueprintUiRoot = "/mnt/data/crucible/blueprint/blueprint.ui"; diff --git a/Crucible.AppHost/resources/crucible-realm.json b/Crucible.AppHost/resources/crucible-realm.json index 444e161..d8879d5 100644 --- a/Crucible.AppHost/resources/crucible-realm.json +++ b/Crucible.AppHost/resources/crucible-realm.json @@ -1761,6 +1761,7 @@ "roles", "profile", "cite", + "gallery", "email" ], "optionalClientScopes": [ @@ -2087,7 +2088,6 @@ "nodeReRegistrationTimeout": -1, "defaultClientScopes": [ "web-origins", - "blueprint", "acr", "openid", "roles", @@ -3639,23 +3639,23 @@ "notBefore" : 0, "groups" : [ ] }, { - "id" : "5cad7558-7a92-4385-8246-1a31aa29aa59", + "id" : "9fd3c38e-58b0-4af1-80d1-1895af91f1f9", "createdTimestamp" : 1730729236429, - "username" : "aschlack", + "username" : "OGadmin", "enabled" : true, "totp" : false, "emailVerified" : false, - "firstName" : "Andrew", - "lastName" : "Schlackman", + "firstName" : "OG", + "lastName" : "Admin", "attributes" : { "terms_and_conditions" : [ "1730729259" ] }, "credentials" : [ { - "id" : "039c2699-f3b6-4f00-a3e3-25ac37964efe", + "id" : "930c2699-f3b6-4f00-a3e3-25ac37964fef", "type" : "password", "userLabel" : "My password", "createdDate" : 1730729246788, - "secretData" : "{\"value\":\"7tyeoBxftnEZ/uSn6bapzvcXK1puAtW0I8rdsiUK8QM=\",\"salt\":\"WI3T2+ACdtSBRoGG6LQrsw==\",\"additionalParameters\":{}}", + "secretData" : "{\"value\":\"3E3znP6H4/QTbd2w1PznMm+PIygqTmvznggrzAarD+8=\",\"salt\":\"ldA2KO1HhEv6xQxWhktn3Q==\",\"additionalParameters\":{}}", "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}" } ], "disableableCredentialTypes" : [ ], @@ -3852,4 +3852,4 @@ "notBefore" : 0, "groups" : [ ] } ] -} \ No newline at end of file +} diff --git a/README.md b/README.md index 8d28446..45a6740 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,10 @@ If you're on a Windows machine, Docker's consumption of your host machine's memo - Memory Limit: 16GB - Disk Usage Limit: 120GB +### zscalar + +The dev container is designed to work with zscalar. You will need to copy the required certs into the **.devcontainer/certs** folder. + ## Troubleshooting This repo is still under construction, so you may run into the occasional challenge or oddity. From our lessons learned: @@ -29,3 +33,26 @@ This repo is still under construction, so you may run into the occasional challe ## Known issues - Some extensions (e.g. C#) very rarely seem to fail to install in the container's VS Code environment. If you see weird intellisense behavior or have compilation/debugging problems, ensure all extensions in the `devcontainers.json` file are installed in your container. + + +# Database seeding and backup +## setup +... using blueprint as the example +create a db-dumps folder under crucible-dev +copy your blueprint.dump file into the db-dumps folder + +## seed/restore a database +navigate to the db-dumps folder in the integrated terminal +drop the blueprint database using pgadmin +create a new blueprint database using pgadmin +assuming crucible-postgres is the postgres container name, +docker cp blueprint.dump crucible-postgres:/tmp/blueprint.dump +docker exec -it crucible-postgres /bin/bash +/usr/lib/postgresql/17/bin/psql --username=postgres blueprint < /tmp/blueprint.dump +exit + +## backup/dump a database +docker exec -it crucible-postgres /bin/bash +pg_dump -U postgres blueprint > /tmp/blueprint.dump +exit +docker cp crucible-postgres:/tmp/blueprint.dump blueprint.dump