Skip to content

Commit

Permalink
Merge pull request #1 from oxidecomputer/new-repo
Browse files Browse the repository at this point in the history
Scrubbed for publish
  • Loading branch information
benjaminleonard authored Mar 11, 2024
2 parents f74dffa + 64a7167 commit f2cfe10
Show file tree
Hide file tree
Showing 139 changed files with 38,624 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fly.toml
/node_modules
*.log
.DS_Store
.env
/.cache
/public/build
/build
12 changes: 12 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": ["@remix-run/eslint-config", "@remix-run/eslint-config/node"],
"ignorePatterns": ["**/*.js", "**/**/*.js"],
"rules": {
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"eqeqeq": "error",
"no-param-reassign": "error",
"no-return-assign": "error",
"react-hooks/exhaustive-deps": "error",
"react-hooks/rules-of-hooks": "error"
}
}
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm install
- name: Check format
run: npm run fmt:check
- name: Typecheck
run: npm run tsc
- name: Lint
run: npm run lint
- name: Unit tests
run: npm test run
- name: Build
run: npm run build
18 changes: 18 additions & 0 deletions .github/workflows/licence-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# To run this check locally, install SkyWalking Eyes somehow
# (https://github.com/apache/skywalking-eyes). On macOS you can `brew install
# license-eye` and run `license-eye header check` or `license-eye header fix`.

name: license-check

on:
push:
branches: [main]
pull_request:

jobs:
license:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check License Header
uses: apache/skywalking-eyes/header@5dfa68f93380a5e57259faaf95088b7f133b5778
34 changes: 34 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Playwright Tests

# This is an unusual job because it's triggered by deploy events rather than
# PR/push. The if condition means we only run on deployment_status events where
# the status is success, i.e., we only run after Vercel deploy has succeeded.

on:
deployment_status:
jobs:
playwright:
if:
github.event_name == 'deployment_status' && github.event.deployment_status.state ==
'success'
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
env:
BASE_URL: ${{ github.event.deployment_status.target_url }}
- uses: actions/upload-artifact@v3
if: always()
with:
name: test-results
path: test-results/
retention-days: 30
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
node_modules
.terraform

.cache
.env
.vercel
.output

/build/
/public/build/
/api/index.js
/api/index.js.map
/api/_assets
tsconfig.tsbuildinfo
test-results/

.DS_Store

/app/components/icons
40 changes: 40 additions & 0 deletions .infra/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions .infra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# RFD Image Hosting

Images for the RFD frontend are stored external to the codebase, and the configuration
stored here defines the GCP infrastructure used to host them.

For images we want to be able to:

1. Require a user to authenticate to access an image even if they know the path to the image
2. Serve images without requiring a trip through the frontend server

Generally any CDN can satisfy point 2 alone. Combining both requirements though is more
difficult without requiring that the CDN understanding user authentication. The solution
here does not fully satisfy the above requirements, but attempts to get close. Images served
from the generated infrastructure require that the image url contain a valid signature that
encodes the image being requested, how long the url is valid for, and the key used to sign
the request. Once a url expires it will begin responding with a 403 error. This allows for
the paths to images to be publicly known without providing generic public access.

Note: Infrastructure configuration is stored in this repository until a point in time where
we have RFD infrastructure that is separate from `cio`. At that point, this infrastructure
should be owned by the RFD service.

### GCP Infrastructure

Image storage and serving is handled by
[Cloud CDN](https://cloud.google.com/cdn/docs/using-signed-urls), backed by
[Cloud Storage](https://cloud.google.com/storage).

```
┌─────────────────┐
│ Cloud CDN ├─ Cache
└────────┬────────┘
┌────────┴────────┐
│ Load Balancer │
└────────┬────────┘
┌────────┴────────┐
│ Backend Bucket ├─ Validate signature
└────────┬────────┘
┌────────┴────────┐
│ Cloud Storage │
└─────────────────┘
```

### Deploy

There are a few steps to deploying this infrastructure:

1. Run `create_cert.sh <project>` to generate a TLS certificate to attach to the load
balancer. We do not create a certificate during Terraform step to prevent the private key
from being written to the tfstate.
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_ssl_certificate
2. Run `terraform apply`. If you changed the name of the certificate created in
`create_cert.sh` or the project to be deployed to, then ensure that the `cert` and
`project` variables are specified.
3. Run `add_signing_key.sh <project> <backend-bucket> <key-name>` to generate a signing key.
This wil output the secret signing key for generating signed urls. Ensure that this key
is stored securely, it can not be recovered. We do not generate this key during the
Terraform step as doing so would write the key to the tfstate.
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_backend_service_signed_url_key
4. Run `activate.sh <project> <storage-bucket>` to grant permission for Cloud CDN to read
from the generated storage bucket.
5. Create a DNS record pointing `static.rfd.shared.oxide.computer` (unless you used a
different domain name) to the IP address allocated by executing the Terraform config.
26 changes: 26 additions & 0 deletions .infra/activate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# Copyright Oxide Computer Company


if [ -z "$1" ] || [ -z "$2" ]
then
echo "A project and storage bucket name must be supplied"
exit 1
fi

PROJECT=$1
BUCKET=$2

PROJECTNUMBER=$(gcloud projects list \
--filter="$(gcloud config get-value project --project $PROJECT)" \
--format="value(PROJECT_NUMBER)" \
--project $PROJECT
)

gsutil iam ch \
serviceAccount:service-$PROJECTNUMBER@cloud-cdn-fill.iam.gserviceaccount.com:objectViewer \
gs://$BUCKET
35 changes: 35 additions & 0 deletions .infra/add_signing_key.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# Copyright Oxide Computer Company


if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
then
echo "A project, backend bucket, and key name must be supplied"
exit 1
fi

PROJECT=$1
BACKEND=$2
KEYNAME=$3

# Key generation uses the recommendation from GCP
# See: https://cloud.google.com/cdn/docs/using-signed-urls#configuring_signed_request_keys
KEY=$(head -c 16 /dev/urandom | base64 | tr +/ -_)
KEYFILE=$(head -c 16 /dev/urandom | base64 | tr +/ -_)

echo $KEY > $KEYFILE

gcloud compute backend-buckets \
add-signed-url-key $BACKEND \
--key-name $KEYNAME \
--key-file $KEYFILE \
--project $PROJECT

echo "Added signing key $KEYNAME to $BACKEND. Ensure that this key is stored securely, it can not be recovered. In the case that it is lost a new key must be created."
echo "Key: $KEY"

rm $KEYFILE
21 changes: 21 additions & 0 deletions .infra/create_cert.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# Copyright Oxide Computer Company


if [ -z "$1" ]
then
echo "A project must be supplied"
exit 1
fi

PROJECT=$1

gcloud compute ssl-certificates create rfd-static-cert \
--description="Static asset serving for RFD frontend" \
--domains="static.rfd.shared.oxide.computer" \
--global \
--project $PROJECT
17 changes: 17 additions & 0 deletions .infra/gcp.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
provider "google" {
project = var.project
region = "us-central1"
zone = "us-central1-c"
}

variable "project" {
default = "websites-326710"
}

variable "prefix" {
default = "rfd-static-assets"
}

variable "cert" {
default = "rfd-static-cert"
}
Loading

0 comments on commit f2cfe10

Please sign in to comment.