Skip to content

Commit

Permalink
feat: Add managed OpenGB (#535)
Browse files Browse the repository at this point in the history
<!-- Please make sure there is an issue that this PR is correlated to. -->

## Changes

<!-- If there are frontend changes, please include screenshots. -->
  • Loading branch information
MasterPtato committed May 18, 2024
1 parent 0e0660a commit 9085d51
Show file tree
Hide file tree
Showing 827 changed files with 18,127 additions and 6,504 deletions.
9 changes: 9 additions & 0 deletions errors/cloudflare/error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name = "CLOUDFLARE_ERROR"
description = "Cloudflare returned an error: {error}"
http_status = 400
---

# Cloudflare Error

An error was returned by a cloudflare API and has been re-routed to this error response.
9 changes: 9 additions & 0 deletions errors/opengb/env-never-deployed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name = "OPENGB_ENV_NEVER_DEPLOYED"
description = "OpenGB environment was never deployed. Deploy it before trying again."
http_status = 400
---

# OpenGB Environment Never Deployed

The requested environment was never deployed. Deploy it before attempting to call this resource again.
9 changes: 9 additions & 0 deletions errors/opengb/env-not-found.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name = "OPENGB_ENV_NOT_FOUND"
description = "OpenGB environment not found."
http_status = 404
---

# OpenGB Environment Not Found

The requested environment could not be found.
9 changes: 9 additions & 0 deletions errors/opengb/invalid-neon-project-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name = "OPENGB_INVALID_NEON_PROJECT_CONFIG"
description = "Neon project config is invalid: {reason}."
http_status = 400
---

# OpenGB Invalid Neon Project Config

The Neon project config given was invalid. See https://api-docs.neon.tech/reference/updateproject for more info.
9 changes: 9 additions & 0 deletions errors/opengb/invalid-variable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name = "OPENGB_INVALID_VARIABLE"
description = "Environment variable is invalid: {reason}."
http_status = 400
---

# OpenGB Invalid Variable

A provided environment variable is invalid.
9 changes: 9 additions & 0 deletions errors/opengb/module-db-not-found.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name = "OPENGB_MODULE_DB_NOT_FOUND"
description = "OpenGB module database not found."
http_status = 404
---

# OpenGB Module DB Not Found

The requested module database could not be found.
9 changes: 9 additions & 0 deletions errors/opengb/project-not-found.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name = "OPENGB_PROJECT_NOT_FOUND"
description = "OpenGB project not found."
http_status = 404
---

# OpenGB Project Not Found

The requested project could not be found.
4 changes: 1 addition & 3 deletions fern/definition/cloud/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ types:
svc_name:
docs: The name of the service.
type: string
ts:
docs: RFC3339 timestamp.
type: datetime
ts: commons.Timestamp
duration:
docs: Unsigned 64 bit integer.
type: long
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,7 @@ types:
name_id:
docs: >-
**Deprecated**
A human readable short identifier used to references resources.
Different than a `rivet.common#Uuid` because this is intended to be
human readable.
Different than `rivet.common#DisplayName` because this should not
include special
characters and be short.
type: optional<string>
type: optional<commons.Identifier>

ValidateGameResponse:
properties:
Expand Down
6 changes: 2 additions & 4 deletions fern/definition/cloud/games/cdn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ types:

CreateGameCdnSiteResponse:
properties:
site_id:
type: uuid
upload_id:
type: uuid
site_id: uuid
upload_id: uuid
presigned_requests: list<uploadCommons.PresignedRequest>
2 changes: 1 addition & 1 deletion fern/definition/cloud/games/namespaces/analytics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ service:
path-parameters:
game_id:
type: uuid

namespace_id:
type: uuid

endpoints:
getAnalyticsMatchmakerLive:
path: /matchmaker/live
Expand Down
2 changes: 1 addition & 1 deletion fern/definition/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ types:
AccountNumber: integer

Timestamp:
type: string
type: datetime
docs: RFC3339 timestamp

GlobalEventNotification:
Expand Down
4 changes: 1 addition & 3 deletions fern/definition/group/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ types:
docs: A group join request.
properties:
identity: identityCommons.Handle
ts:
docs: RFC3339 timestamp.
type: datetime
ts: commons.Timestamp

Member:
docs: A group member.
Expand Down
1 change: 0 additions & 1 deletion fern/definition/identity/__package__.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ service:
request:
name: GetHandlesRequest
query-parameters:
# TODO: how is this list serialized over the wire
# With allow-multiple, Fern assumes that lists are sent over the wire as
# param=a&param=b&param=c.
identity_ids:
Expand Down
2 changes: 1 addition & 1 deletion fern/definition/identity/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ types:
GlobalEvent:
docs: An event relevant to the current identity.
properties:
ts: datetime
ts: commons.Timestamp
kind: GlobalEventKind
notification: optional<GlobalEventNotification>

Expand Down
26 changes: 17 additions & 9 deletions infra/tf/dns/cert_packs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ locals {
certificate_authority = "lets_encrypt"
}

# TODO: Only if we use deprecated subdomains
# Allow CLoudflare to serve TLS requests at the edge for our wildcard
# Allow Cloudflare to serve TLS requests at the edge for our wildcard
# subdomains.
#
# This requires paying money for these certs.
Expand All @@ -29,13 +28,22 @@ resource "cloudflare_certificate_pack" "main" {
certificate_authority = local.certificate_authority
# The certificate must include the root domain in it.
#
# We convert to set then back to list to remove potential duplicates of the root zoon.
hosts = sort(tolist(toset([
data.cloudflare_zone.main.name,
var.domain_main,
"*.${var.domain_main}",
"*.api.${var.domain_main}",
])))
# We convert to set then back to list to remove potential duplicates of the root zone.
hosts = sort(tolist(toset(
flatten([
[
data.cloudflare_zone.main.name,
var.domain_main,
"*.${var.domain_main}",
# TODO: Only if we use deprecated subdomains
"*.api.${var.domain_main}",
],
var.opengb_enabled ? [
"*.opengb.${var.domain_main}",
"db.opengb-internal.${var.domain_main}"
] : []
])
)))
type = "advanced"
validation_method = "txt"
validity_days = 90
Expand Down
5 changes: 5 additions & 0 deletions infra/tf/dns/vars.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ variable "extra_dns" {
}))
}

# MARK: OpenGB
variable "opengb_enabled" {
type = bool
}

# MARK: Cloudflare
variable "cloudflare_account_id" {
type = string
Expand Down
13 changes: 12 additions & 1 deletion infra/tf/tls/cloudflare.tf
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,18 @@ resource "tls_cert_request" "cf_origin_rivet_gg" {

resource "cloudflare_origin_ca_certificate" "rivet_gg" {
csr = tls_cert_request.cf_origin_rivet_gg.cert_request_pem
hostnames = ["*.${var.domain_main}", "${var.domain_main}", "*.api.${var.domain_main}", "api.${var.domain_main}"]
hostnames = flatten([
[
"*.${var.domain_main}",
"${var.domain_main}",
"*.api.${var.domain_main}",
"api.${var.domain_main}",
],
var.opengb_enabled ? [
"*.opengb.${var.domain_main}",
"db.opengb-internal.${var.domain_main}"
] : []
])
request_type = "origin-rsa"
requested_validity = 15 * 365
}
Expand Down
5 changes: 5 additions & 0 deletions infra/tf/tls/vars.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ variable "prometheus_enabled" {
type = bool
}

# MARK: OpenGB
variable "opengb_enabled" {
type = bool
}

# MARK: K8s
variable "kubeconfig_path" {
type = string
Expand Down
6 changes: 6 additions & 0 deletions lib/bolt/config/src/ns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ pub struct Rivet {
pub cdn: Cdn,
#[serde(default)]
pub billing: Option<RivetBilling>,
#[serde(default)]
pub opengb: Option<RivetOpenGb>,
}

#[derive(Serialize, Deserialize, Clone, Debug, Default)]
Expand All @@ -525,6 +527,10 @@ pub struct Telemetry {
pub disable: bool,
}

#[derive(Serialize, Deserialize, Clone, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct RivetOpenGb {}

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
pub enum RivetAccess {
Expand Down
16 changes: 12 additions & 4 deletions lib/bolt/core/src/context/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,16 @@ impl ProjectContextData {
if self.ns().dns.is_some() {
assert_eq!(
80, *api_http_port,
"api_http_port must be 80 if dns is configured"
"api_http_port must be 80 if DNS is configured"
);
assert_eq!(
Some(443),
*api_https_port,
"api_https_port must be 443 if dns is configured"
"api_https_port must be 443 if DNS is configured"
);
assert_eq!(
9000, *minio_port,
"minio_port must not be changed if dns is configured"
"minio_port must not be changed if DNS is configured"
);
}
}
Expand All @@ -218,11 +218,19 @@ impl ProjectContextData {

assert!(
self.dns_enabled(),
"must have dns provider configured with a distributed cluster"
"must have DNS configured with a distributed cluster"
);
}
}

// MARK: OpenGB
if self.ns().rivet.opengb.is_some() {
assert!(
self.ns().dns.is_some(),
"must have DNS configured with for OpenGB"
);
}

// MARK: Cluster Provisioning
if let Some(cluster) = self
.ns()
Expand Down
10 changes: 10 additions & 0 deletions lib/bolt/core/src/context/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,16 @@ impl ServiceContextData {
);
}

// OpenGB
if project_ctx.ns().rivet.opengb.is_some() {
let opengb_output = terraform::output::read_opengb(&project_ctx).await;

env.insert(
"CLOUDFLARE_OPENGB_DISPATCHER_NAMESPACE".into(),
opengb_output.dispatcher_namespace_name.to_string(),
);
}

if self.depends_on_captcha() {
if let Some(hcaptcha) = &project_ctx.ns().captcha.hcaptcha {
env.insert(
Expand Down
7 changes: 1 addition & 6 deletions lib/bolt/core/src/dep/one_password/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ pub async fn command(service_token: Option<&str>) -> Command {
cmd.arg("op");

let installed = cmd.exec_quiet(true, true).await.is_ok();

if !installed {
panic!("1Password secret management is enabled in the namespace config but the 1Password CLI (`op`) is not installed");
}
assert!(installed, "1Password secret management is enabled in the namespace config but the 1Password CLI (`op`) is not installed");

let mut cmd = Command::new("op");

Expand All @@ -22,8 +19,6 @@ pub async fn command(service_token: Option<&str>) -> Command {
}

cmd.env("OP_SERVICE_ACCOUNT_TOKEN", service_token);
} else {
eprintln!("WARNING: 1Password secret management is enabled in the namespace config but the '1password.service_account_token' secret is not set.\n");
}

cmd
Expand Down
14 changes: 12 additions & 2 deletions lib/bolt/core/src/dep/terraform/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ async fn vars(ctx: &ProjectContext) {
json!(config.rivet.provisioning.is_some()),
);

// OpenGB
vars.insert(
"opengb_enabled".into(),
json!(config.rivet.opengb.is_some()),
);

// Tunnels
if let Some(ns::Dns {
provider: Some(ns::DnsProvider::Cloudflare { access, .. }),
Expand Down Expand Up @@ -304,10 +310,14 @@ async fn vars(ctx: &ProjectContext) {
"name": domain_main_api,
}));

// OGS
// OpenGB
extra_dns.push(json!({
"zone_name": "main",
"name": format!("*.opengb.{domain_main}"),
}));
extra_dns.push(json!({
"zone_name": "main",
"name": format!("*.ogs.{domain_main}"),
"name": format!("db.opengb-internal.{domain_main}"),
}));

// Add services
Expand Down
9 changes: 9 additions & 0 deletions lib/bolt/core/src/dep/terraform/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ pub struct DnsZones {
pub job: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct OpenGb {
pub dispatcher_namespace_name: TerraformOutputValue<String>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct KubernetesClusterAws {
pub eks_admin_role_arn: TerraformOutputValue<String>,
Expand Down Expand Up @@ -120,6 +125,10 @@ pub async fn read_redis(ctx: &ProjectContext) -> Redis {
}
}

pub async fn read_opengb(ctx: &ProjectContext) -> OpenGb {
read_plan::<OpenGb>(ctx, "opengb").await
}

/// Reads a Terraform plan's output and decodes in to type.
pub async fn read_plan<T: serde::de::DeserializeOwned>(ctx: &ProjectContext, plan_id: &str) -> T {
let terraform_plans = crate::tasks::infra::all_terraform_plans(ctx).unwrap();
Expand Down
Loading

0 comments on commit 9085d51

Please sign in to comment.