In monorepo:
```
cmd/my-service/main.go
-> cmd/my-service/service
-> cmd/my-service/internal/...
```
Outside monorepo a similar unnested structure aligns with this as well:
```
cmd/my-service <- command
service/... <- entrypoint
internal/... <- internal implementation
```
## Test plan
Basic example builds and runs: `sg run msp-example`
Exports package `github.com/sourcegraph/sourcegraph/lib/managedservicesplatform/runtime/contract` to expose previously-internal env-configuration (the "MSP contract") loading, helpers, and configuration. This allows programs that aren't 100% in the MSP runtime ecosystem yet (hopefully reducing future barrier to entry), or are in particular scenarios where they might not want to use runtime ([e.g. MSP jobs which doesn't have proper runtime support yet](https://sourcegraph.slack.com/archives/C06062P5TS5/p1711663052720289)), to integrate with MSP-provisioned infrastructure like BigQuery, PostgreSQL, and even Sentry etc. directly.
The recommended path will still be to build a `runtime`-compliant interface, but it can be a hassle to migrate sometimes, and as mentioned, we don't properly support jobs yet.
Simple example:
```go
// Parse the environment into an Env instance.
e, _ := contract.ParseEnv([]string{"MSP=true"})
// Extract Contract instance from Env configuration.
c := contract.New(logger, service, e)
// Also load other custom configuration here from Env you want here
// Check for errors on Env retrieval (missing/invalid values, etc.)
if err := e.Validate(); err != nil { ... }
// Use Contract helpers and configuration values
writer, _ := c.BigQuery.GetTableWriter(ctx, "my-table")
writer.Write(...)
```
## Test plan
There are no functionality changes, only code moving. But, ran some sanity checks:
```
sg run msp-example
sg run telemetry-gateway
sg run pings
```
---------
Co-authored-by: Chris Smith <chrsmith@users.noreply.github.com>
This change:
1. Renames `lib/managedservicesplatform/service` to `lib/managedservicesplatform/runtime` - I've been referring to it as runtime, and we use the word "service" a lot already, so this makes it easier to refer to and is more descriptive.
2. Makes everything under `lib/managedservicesplatform` a separate submodule from `lib` - the MSP runtime contributes a lot of dependencies to `lib`, and I don't think we should keep bloating `lib` to add more functionality to MSP.
3. Adds OpenTelemetry tracing and metrics configuration similar to the setup used by Cody Gateway and Telemetry Gateway
This PR has 3 major changes:
1. Provisioning a Cloud SQL PostgreSQL instance: `resource.postgreSQL`
2. Updates to the MSP runtime for connecting to the database
3. Publishable `msp-example` for the `msp-testbed` deployment, for testing integrations and other MSP features, and adds an example Gorm setup
Closes https://github.com/sourcegraph/sourcegraph/issues/56848. For more context, see go/msp
### `resource.postgreSQL`
This change adds `resource.postgreSQL` to the spec for provisioning a Cloud SQL database. Example:
```yaml
resources:
postgreSQL:
databases: ["primary"]
cpu: 1
memoryGB: 4
```
When configured, a Cloud SQL instance is provisioned, and the Cloud Run workload SA is granted access to it. The specified `databases` are also created. `cpu` and `memoryGB` are used to generate the custom VM to provision the instance with. A lot of the base configuration for the database instance are taken directly from what we use in Cloud: 9cac1b1aa0/internal/resource/sql/sql.go (L116), and is similar to the Redis setup, in that we need the private peering VPC and install additional certs on the Cloud Run instance.
### MSP runtime
`service.Contract` now has a helper, `GetPostgreSQLDB(database)`, for generating the appropriate configuration for creating a connection to a given database and returning a `sql.DB`, which most libraries have adapters for. The helper sets up `pgx.ConnConfig` that uses workload identity to connect directly to Cloud SQL, following the guide here: https://github.com/GoogleCloudPlatform/cloud-sql-go-connector?tab=readme-ov-file#automatic-iam-database-authentication
In local dev, `PGDSN` can be used to hardcode an appropriate value.
### `msp-example`
I've moved the MSP example from #56846 to the top-level `cmd/msp-example,` and set up some guidance for publishing it. This service now also includes a simple database connection and setup using Gorm, used by https://github.com/sourcegraph/accounts.sourcegraph.com, and can be used for testing, e.g. https://github.com/sourcegraph/managed-services/pull/87
## Test plan
- [x] Deploy https://github.com/sourcegraph/managed-services/pull/87, which will connect to the database and set up some tables
- [x] Review diff: https://github.com/sourcegraph/managed-services/actions/runs/6951246277
- [x] Tear down database in https://github.com/sourcegraph/managed-services/pull/87, with caveat: requires state surgery. Should be rare enough (we might prefer to tear down environments entirely) - see docstrings in package `postgresqlroles`
---------
Co-authored-by: Michael Lin <mlzc@hey.com>
Co-authored-by: Joe Chen <joe@sourcegraph.com>