diff --git a/README.md b/README.md index a9c6b8fac..886736f15 100644 --- a/README.md +++ b/README.md @@ -96,13 +96,6 @@ The Convene UI is based on Rails standard templating system, with heavy use of: which loads all `app/javascript/*_controllers.js` files - [Tailwind CSS](https://tailwindcss.com/) to help speed up making good-looking UIs -Jitsi is Convene's video call infrastructure. The -[video_room_controller.js](./app/javascript/controllers/video_room_controller.js) is the entry point -where we load a Jitsi video call iframe into Convene's UI. - -If you want to run Jitsi locally, see the configuration provided in -[`infrastructure/jitsi-meet-local`](./infrastructure/jitsi-meet-local/README.md). - See [Architecture](./CONTRIBUTING.md#11-architecture) for how Convene is architected. ## Configuring Your Development Machine diff --git a/app/assets/stylesheets/application.postcss.css b/app/assets/stylesheets/application.postcss.css index 1b9e23fc1..43128e8b4 100644 --- a/app/assets/stylesheets/application.postcss.css +++ b/app/assets/stylesheets/application.postcss.css @@ -7,4 +7,3 @@ @import "./utilities.scss"; @import "./components.scss"; -@import "./furniture.scss"; diff --git a/app/assets/stylesheets/furniture.scss b/app/assets/stylesheets/furniture.scss deleted file mode 100644 index 4c82d5296..000000000 --- a/app/assets/stylesheets/furniture.scss +++ /dev/null @@ -1,2 +0,0 @@ - -@import "../../furniture/video_bridge/index.css" \ No newline at end of file diff --git a/app/furniture/furniture.rb b/app/furniture/furniture.rb index dc7b590fd..61dcece34 100644 --- a/app/furniture/furniture.rb +++ b/app/furniture/furniture.rb @@ -7,7 +7,6 @@ module Furniture journal: Journal, markdown_text_block: MarkdownTextBlock, marketplace: Marketplace, - video_bridge: VideoBridge, livestream: Livestream, embedded_form: EmbeddedForm, }.freeze diff --git a/app/furniture/video_bridge.rb b/app/furniture/video_bridge.rb deleted file mode 100644 index 058a748ad..000000000 --- a/app/furniture/video_bridge.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -# Provides an iFramed Jitsi Meet to a {Room}. -class VideoBridge < FurniturePlacement - def self.from_placement(placement) - placement.becomes(self) - end -end diff --git a/app/furniture/video_bridge/_form.html.erb b/app/furniture/video_bridge/_form.html.erb deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/furniture/video_bridge/index.css b/app/furniture/video_bridge/index.css deleted file mode 100644 index 6309a0b61..000000000 --- a/app/furniture/video_bridge/index.css +++ /dev/null @@ -1,3 +0,0 @@ -.--open { - height: 100vh; -} diff --git a/app/furniture/video_bridge/index.js b/app/furniture/video_bridge/index.js deleted file mode 100644 index 9bd2ef1a5..000000000 --- a/app/furniture/video_bridge/index.js +++ /dev/null @@ -1,26 +0,0 @@ - -import { Controller } from "@hotwired/stimulus" -import VideoBridge from "./video_bridge.js"; -import { application } from "../../javascript/controllers/application.js" - -class VideoBridgeController extends Controller { - static targets = [ "wrapper" ] - - connect() { - this.videoBridge = new VideoBridge(this.data.get('videoHost'), this.wrapperTarget); - this.videoBridge.addEventListener('enteredRoom', () => { - this.wrapperTarget.classList.add('--open'); - }); - this.videoBridge.addEventListener('exitedRoom', () => { - this.wrapperTarget.classList.remove('--open'); - }); - - this.videoBridge.enterRoom(this.data.get('name')); - } - - disconnect() { - this.videoBridge.exitRoom(); - } -} - -application.register("video-bridge", VideoBridgeController) diff --git a/app/furniture/video_bridge/video_bridge.js b/app/furniture/video_bridge/video_bridge.js deleted file mode 100644 index 8e6304e0e..000000000 --- a/app/furniture/video_bridge/video_bridge.js +++ /dev/null @@ -1,55 +0,0 @@ -import { EventTarget } from 'event-target-shim'; - -const eventBus = new EventTarget() -export default class VideoBridge { - constructor(domain, parentNode) { - this.domain = domain; - this.parentNode = parentNode; - this.connectJitsiApi(); - } - - enterRoom(roomName) { - this.roomName = roomName; - this.connectJitsiApi(); - this.dispatchEvent(new CustomEvent("enteredRoom")); - } - - exitRoom() { - this.jitsi.dispose(); - this.dispatchEvent(new CustomEvent("exitedRoom")); - } - - addEventListener(type, listener, option) { - eventBus.addEventListener(type, listener, option); - } - - dispatchEvent(event) { - eventBus.dispatchEvent(event); - } - - connectJitsiApi() { - if (!this.roomName) return; - this.jitsi = new JitsiMeetExternalAPI(this.domain, this.jitsiApiOption()); - this.jitsi.on('readyToClose', () => this.exitRoom(true)); - } - - jitsiApiOption() { - return { - roomName: this.roomName, - parentNode: this.parentNode, - interfaceConfigOverwrite: { - TOOLBAR_BUTTONS: ['microphone', 'camera', 'desktop', 'tileview', 'hangup'], - DISABLE_JOIN_LEAVE_NOTIFICATIONS: true, - DISABLE_PRESENCE_STATUS: true, - MOBILE_APP_PROMO: false, - APP_NAME: 'Convene', - DISABLE_RINGING: true, - SETTINGS_SECTIONS: [], - DEFAULT_REMOTE_DISPLAY_NAME: 'Participants', - }, - configOverwrite: { - disableDeepLinking: true, - }, - }; - } -} diff --git a/app/furniture/video_bridges/_video_bridge.html.erb b/app/furniture/video_bridges/_video_bridge.html.erb deleted file mode 100644 index dec8bbc57..000000000 --- a/app/furniture/video_bridges/_video_bridge.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -
-
- - - -<%= javascript_include_tag "furniture_video_bridge", "data-turbo-track": "reload", defer: true %> \ No newline at end of file diff --git a/app/models/blueprint.rb b/app/models/blueprint.rb index b8770b78b..4b5c068e1 100644 --- a/app/models/blueprint.rb +++ b/app/models/blueprint.rb @@ -104,12 +104,8 @@ def space_attributes BLUEPRINTS = { system_test: { - entrance: "entrance-hall", - utility_hookups: [ - {utility_slug: :jitsi, name: "Jitsi", configuration: - {meet_domain: "convene-videobridge-zinc.zinc.coop"}} - ], + utility_hookups: [ ], members: [{email: "space-owner@example.com"}, {email: "space-member@example.com"}], rooms: [ @@ -120,7 +116,6 @@ def space_attributes access_code: nil, furniture_placements: { markdown_text_block: {content: "# Welcome!"}, - video_bridge: {}, } }, { @@ -129,7 +124,6 @@ def space_attributes access_level: :unlocked, access_code: nil, furniture_placements: { - video_bridge: {} } }, { @@ -137,27 +131,21 @@ def space_attributes publicity_level: :listed, access_level: :locked, access_code: :secret, - furniture_placements: { - video_bridge: {} - } + furniture_placements: { } }, { name: "Unlisted Room 1", publicity_level: :unlisted, access_level: :unlocked, access_code: nil, - furniture_placements: { - video_bridge: {} - } + furniture_placements: { } }, { name: "Unlisted Room 2", publicity_level: :unlisted, access_level: :unlocked, access_code: nil, - furniture_placements: { - video_bridge: {} - } + furniture_placements: { } }, { name: "Entrance Hall", @@ -165,7 +153,6 @@ def space_attributes furniture_placements: { markdown_text_block: {content: "# Wooo!"}, } - } ] } @@ -173,43 +160,6 @@ def space_attributes # @todo migrate this to a private configuration file! CLIENTS = [{ - client: { - name: "Zinc", - space: { - members: [{email: "zee@zinc.coop"}, {email: "cheryl@zinc.coop"}], - name: "Zinc", branded_domain: "meet.zinc.coop", - entrance: "lobby", - utility_hookups: [ - { - utility_slug: :jitsi, name: "Jitsi", configuration: - {meet_domain: "convene-videobridge-zinc.zinc.coop"} - } - ], - rooms: [{ - name: "Lobby", - access_level: :unlocked, - publicity_level: :unlisted, - furniture_placements: { - markdown_text_block: {} - } - }, { - name: "Ada", - access_level: :unlocked, - publicity_level: :listed, - furniture_placements: { - video_bridge: {} - } - }, { - name: "Talk to Zee", - access_level: :unlocked, - publicity_level: :unlisted, - furniture_placements: { - video_bridge: {} - } - }] - } - } - }, { client: { name: "Zinc", space: { diff --git a/app/models/demo_space.rb b/app/models/demo_space.rb index 4b79ec453..bd9dbbecb 100644 --- a/app/models/demo_space.rb +++ b/app/models/demo_space.rb @@ -47,7 +47,7 @@ def self.prepare name: "Zinc", space: { name: "Convene Demo", - utility_hookups: utility_hookups, + utility_hookups: [], branded_domain: "convene-demo.zinc.coop", members: [{email: "zee@zinc.coop"}, {email: "vivek@zinc.coop"}], @@ -55,11 +55,4 @@ def self.prepare } }).find_or_create! end - - def self.utility_hookups - [ - {utility_slug: :jitsi, name: "Jitsi", configuration: - {meet_domain: "convene-videobridge-zinc.zinc.coop"}} - ] - end end diff --git a/app/models/room.rb b/app/models/room.rb index d8649a2d7..96018d4dc 100644 --- a/app/models/room.rb +++ b/app/models/room.rb @@ -66,10 +66,6 @@ def full_slug "#{space.slug}--#{slug}" end - def video_host - space.jitsi_meet_domain - end - def enterable?(access_code) return true if access_level == "unlocked" diff --git a/app/models/space.rb b/app/models/space.rb index ca3716875..f1d289e97 100644 --- a/app/models/space.rb +++ b/app/models/space.rb @@ -55,13 +55,6 @@ class Space < ApplicationRecord # @returns {ActiveRecord::Relation} has_many :utility_hookups, dependent: :destroy_async - def jitsi_meet_domain - jitsi_hookup = utility_hookups.find_by(utility_slug: :jitsi) - return if jitsi_hookup.blank? - - Utilities.from_utility_hookup(jitsi_hookup).meet_domain - end - def parent_location [] end diff --git a/app/utilities/jitsi/jitsi_utility.rb b/app/utilities/jitsi/jitsi_utility.rb deleted file mode 100644 index 2b4d3ca94..000000000 --- a/app/utilities/jitsi/jitsi_utility.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module Jitsi - # Provides Jitsi Video functionality to a {Space} - # @see https://jitsi.org - class JitsiUtility < Utility - def meet_domain - configuration["meet_domain"] - end - - def meet_domain=(value) - configuration["meet_domain"] = value - end - - def attribute_names - super + [:meet_domain] - end - end -end diff --git a/app/utilities/jitsi/jitsi_utility_policy.rb b/app/utilities/jitsi/jitsi_utility_policy.rb deleted file mode 100644 index 83298e304..000000000 --- a/app/utilities/jitsi/jitsi_utility_policy.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Jitsi - class JitsiUtilityPolicy < UtilityPolicy - def permitted_attributes(_params) - [:meet_domain] - end - end -end diff --git a/app/utilities/utilities.rb b/app/utilities/utilities.rb index 02598db98..0d0336e51 100644 --- a/app/utilities/utilities.rb +++ b/app/utilities/utilities.rb @@ -10,7 +10,6 @@ # @see features/utilities/ module Utilities REGISTRY = { - jitsi: Jitsi::JitsiUtility, stripe: Stripe::StripeUtility }.freeze diff --git a/bin/jitsi-local-run b/bin/jitsi-local-run deleted file mode 100755 index e785d9fde..000000000 --- a/bin/jitsi-local-run +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -# Script to start a local dockerized Jitsi infrastructure chain, running on the default Docker machine. -# Script assumes that it is being called from the root of the repo, as bin/jitsi-local-run - -set -e - -if [[ -z "${DOCKER_HOST}" ]]; then - echo "Couldn't find a DOCKER_HOST env variable. This script depends on a running Docker machine." - echo "Please start Docker and set up your environment, and try this script again." - exit 1 -fi - -# Example DOCKER_HOSTs that work: `tcp://192.168.0.1:2375` -# Example DOCKER_HOSTs that do not work: `192.168.0.1`, `tcp://192.168.0.1` -DOCKER_HOST_AND_PORT=$(echo $DOCKER_HOST | cut -d / -f 3) -DOCKER_HOST_IP=$(echo $DOCKER_HOST_AND_PORT | cut -d : -f 1) -DOCKER_HOST_PORT=$(echo $DOCKER_HOST_AND_PORT | cut -d : -f 2) - -echo "Attempting to verify that a docker machine is running at ${DOCKER_HOST_IP}:${DOCKER_HOST_PORT}" -nc -z $DOCKER_HOST_IP $DOCKER_HOST_PORT - -# This hostname should match what is set as the local hostname when setting up the Docker image. -# See the HOSTNAME variable in infrastructure/dev/install-jitsi-meet.sh -CONTAINER_HOSTNAME=jitsi -IMAGE_TAG=jitsi_local -CONTAINER_NAME=jitsi_local - -if [[ "$(docker images -q $IMAGE_TAG 2> /dev/null)" == "" ]]; then - echo "Couldn't find Docker image named $IMAGE_TAG. Building a new one." - cd infrastructure/jitsi-meet-local && docker build -f jitsi-meet.Dockerfile . --tag $IMAGE_TAG -fi - -echo "Starting Docker container..." -docker run -d -p 80:80 -p 443:443 -p 8080:8080 --hostname $CONTAINER_HOSTNAME --name $CONTAINER_NAME $IMAGE_TAG - -echo "Jitsi services are now running in a Docker container." -echo "Add the following line to your /etc/hosts: $DOCKER_HOST_IP $CONTAINER_HOSTNAME" -echo "Then, to verify your installation, open the Jitsi Meet web UI at https://$CONTAINER_HOSTNAME" diff --git a/db/migrate/20230119005121_remove_video_bridge_furniture.rb b/db/migrate/20230119005121_remove_video_bridge_furniture.rb new file mode 100644 index 000000000..33e3822da --- /dev/null +++ b/db/migrate/20230119005121_remove_video_bridge_furniture.rb @@ -0,0 +1,19 @@ +class RemoveVideoBridgeFurniture < ActiveRecord::Migration[7.0] + # As of 2023/1/28, these are the video-bridge placements in production + # > FurniturePlacement.where(furniture_kind: "video_bridge").map {|fp| [fp.id, fp.room.slug, fp.room.space.slug]} + # [["c868b70f-00a8-4889-92fb-8a39106a507d", "zee-s-desk", "convene-demo"], + # ["be167a5b-628c-4366-b191-d8804813b77c", "vivek-s-desk", "convene-demo"], + # ["d9196ae8-9fe6-4bfd-875b-3e593411fed4", "water-cooler", "convene-demo"], + # ["4e2116fc-eb4c-4466-b269-b5cd0da8f1f2", "the-ada-lovelace-room", + # "convene-demo"], ["ca5ea9f3-1680-4528-ae4b-b13ce499cdf3", "locked-room", + # "convene-demo"], ["eaa117fc-2326-4903-9cfd-92e68d0ed38d", "viveks-desk", + # "avigno"], ["402a54c6-513f-4d35-a416-b0e9089f72bb", "music-room", "avigno"], + # ["fd1a0b4c-973b-4078-a2eb-5b45f7b89731", "common-room", "avigno"]] + def up + FurniturePlacement.where(furniture_kind: "video_bridge").destroy_all + end + + def down + ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20230119012952_remove_jitsi_plaid_utilities.rb b/db/migrate/20230119012952_remove_jitsi_plaid_utilities.rb new file mode 100644 index 000000000..b47387ebe --- /dev/null +++ b/db/migrate/20230119012952_remove_jitsi_plaid_utilities.rb @@ -0,0 +1,9 @@ +class RemoveJitsiPlaidUtilities < ActiveRecord::Migration[7.0] + def up + UtilityHookup.where(utility_slug: ["plaid", "jitsi"]).destroy_all + end + + def down + ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20230119014621_drop_jitsi_meet_domain.rb b/db/migrate/20230119014621_drop_jitsi_meet_domain.rb new file mode 100644 index 000000000..fce8a5989 --- /dev/null +++ b/db/migrate/20230119014621_drop_jitsi_meet_domain.rb @@ -0,0 +1,5 @@ +class DropJitsiMeetDomain < ActiveRecord::Migration[7.0] + def change + remove_column :spaces, :jitsi_meet_domain, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 3f39a4010..e4d8b9b7e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_01_12_024425) do +ActiveRecord::Schema[7.0].define(version: 2023_01_19_014621) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -208,7 +208,6 @@ create_table "spaces", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "client_id" - t.string "jitsi_meet_domain" t.string "name" t.string "slug" t.datetime "created_at", null: false diff --git a/features/harness/RoomPage.js b/features/harness/RoomPage.js index f9d43eebf..4425b9f61 100644 --- a/features/harness/RoomPage.js +++ b/features/harness/RoomPage.js @@ -20,9 +20,7 @@ class RoomPage extends Page { accessCodeForm() { return this.component(".access-code-form"); } - videoPanel() { - return this.component("[name*='jitsiConferenceFrame']"); - } + path() { return `/spaces/${this.room.space.slug}/rooms/${this.room.slug}`; } diff --git a/features/steps/room_steps.js b/features/steps/room_steps.js index 919eca85b..b75fd3058 100644 --- a/features/steps/room_steps.js +++ b/features/steps/room_steps.js @@ -67,7 +67,7 @@ When("the {actor} taps the {room} in the Room Picker", function (actor, room) { }); Then("the {actor} is placed in the {room}", async function (actor, room) { const roomPage = new RoomPage(this.driver, room); - assert(await roomPage.videoPanel().isDisplayed()); + assert(await roomPage.hasContent(room.name)); }); Then("the {actor} is not placed in the {room}", function (actor, room) { // Write code here that turns the phrase above into concrete actions diff --git a/features/steps/utility_hookup_steps.js b/features/steps/utility_hookup_steps.js index 852f96a87..9dc953547 100644 --- a/features/steps/utility_hookup_steps.js +++ b/features/steps/utility_hookup_steps.js @@ -1,17 +1,20 @@ -import { Given, When, Then } from "@cucumber/cucumber"; +import { When, Then } from "@cucumber/cucumber"; import { SpaceEditPage } from "../harness/Pages.js"; import { Actor, Space } from "../lib/index.js"; + When("a Space Owner adds a Hookup to their Space", async function () { this.actor = new Actor("Space Owner", "space-owner@example.com"); await this.actor.signIn(this.driver); this.space = new Space({ name: "System Test" }); const page = new SpaceEditPage(this.driver, this.space); - await page.visit().then((p) => p.addUtilityHookup("Jitsi Meet")); + await page.visit().then((p) => p.addUtilityHookup("stripe")); }); + Then("the Space Owner can configure that Hookup for their Space", function () { // Write code here that turns the phrase above into concrete actions return "pending"; }); + Then("that Hookup can not be used by Furniture in the Space", function () { // Write code here that turns the phrase above into concrete actions return "pending"; diff --git a/infrastructure/CHANGELOG.md b/infrastructure/CHANGELOG.md deleted file mode 100644 index 43a7ea93b..000000000 --- a/infrastructure/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# Convene::Infrastructure Changelog - -HEAD --------- -### Added -- [Operator Provisions an Always On Virtual Office Space on AWS ](https://github.com/zinc-collective/convene/issues/2) -- [Always-on Convene Spaces Restart in a Nightly Maintenance Window](https://github.com/zinc-collective/convene/issues/17) -- [Operator Provisions an Always On Virtual Office Space on Vultr](https://github.com/zinc-collective/convene/issues/27) -- [Multiple Operators may SSH into Provisioned Convene instances](https://github.com/zinc-collective/convene/issues/29) diff --git a/infrastructure/README.md b/infrastructure/README.md deleted file mode 100644 index ddb97aa96..000000000 --- a/infrastructure/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# Convene::Infrastructure - -Tools to manage the infrastructure for Convene clients. - -## Usage - -See documentation in the `features` directory to learn how to run the commands -that provision client infrastructure. - -Convene::Infrastructure uses the following tools to ensure broad -interoperability between infrastructure providers. - -- [Packer](https://www.packer.io/intro/getting-started/) -- [Terraform](https://learn.hashicorp.com/terraform/getting-started/install.html) -- [Ansible](https://www.ansible.com/resources/get-started) - -Please ensure all three are installed and run from your command line. - -### Creating Your Own Convene Space - -There are two steps to creating a Convene Video Space: - -1. [Building a Space's Blueprint](#building-a-spaces-blueprint) -1. [Provisioning a Space from the Blueprint](#provisioning-a-space-from-the-blueprint) - -Every Convene Video Space has a _Blueprint_. Blueprints define: - -1. The Infrastructure provider(s) your Space will run on. -2. The Space's security, reliability, and performance configuration - specification. -3. The [golden image(s)] that will be placed within the Infrastructure provider - when provisioned. - -Each Blueprint includes the following files: - -- `infrastructure.tf`: Terraform file configuring the infrastructure. -- `public.tfvars`: Variables that are safe to share with the world. -- `secrets.tfvars`: API credentials or other variables that are not safe to save - to the repository. `.gitignore`d by default. - -There are example Blueprints for: - -- [Amazon Web Services], [in `clients/convene-test-aws.zinc.coop`] -- [Vultr], [in `clients/convene-test-vultr.zinc.coop`] - -[in `clients/convene-test-aws.zinc.coop`]: ./clients/convene-test-aws.zinc.coop -[in `clients/convene-test-vultr.zinc.coop`]: - ./clients/convene-test-vultr.zinc.coop -[amazon web services]: https://aws.amazon.com/ -[vultr]: https://www.vultr.com/ -[golden image(s)]: https://www.quora.com/What-is-golden-image - -#### Building a Space's Blueprint - -For step-by-step instructions for building a Space, see the "Operator -builds..." scenarios in [`features/video-spaces.feature`]. - -A visual overview of what happens when an Operator builds a Blueprint is as -follows: - -![Operator Builds a Convene Space](./docs/operator-builds-a-convene-space.png) - -[`features/video-spaces.feature`]: ./features/video-spaces.feature - -#### Provisioning a Space from the Blueprint - -For step-by-step instructions for building a Space, see the "Operator -Provisions..." scenarios in [`features/video-spaces.feature`]. diff --git a/infrastructure/clients/aws-example/infrastructure.tf b/infrastructure/clients/aws-example/infrastructure.tf deleted file mode 100644 index d16916dd3..000000000 --- a/infrastructure/clients/aws-example/infrastructure.tf +++ /dev/null @@ -1,170 +0,0 @@ -variable "cloudflare_email" { - type = string -} - - -variable "cloudflare_api_key" { - type = string -} - -variable "cloudflare_zone_id" { - type = string -} - -provider "cloudflare" { - version = "~> 2.0" - email = var.cloudflare_email - api_key = var.cloudflare_api_key -} - -# Create a record -resource "cloudflare_record" "convene-test-aws" { - zone_id = var.cloudflare_zone_id - name = "convene-test-aws" - value = aws_eip.convene_ip.public_ip - type = "A" - ttl = 1 -} - -provider "aws" { - region = "us-west-1" -} - -data "aws_ami" "convene_ami" { - most_recent = true - owners = ["self"] - - filter { - name = "name" - values = ["convene-jitsi-convene-test.zinc.coop*"] - } -} - -resource "aws_instance" "convene_video" { - ami = data.aws_ami.convene_ami.id - instance_type = "t2.micro" - tags = { - Name = "convene-test-aws.zinc.coop" - } - security_groups = [aws_security_group.allow_ssh.name, - aws_security_group.allow_http.name, - aws_security_group.allow_tls.name, - aws_security_group.allow_jitsi_video.name] - key_name = "deployer-key" -} - -resource "aws_eip" "convene_ip" { - instance = aws_instance.convene_video.id -} - - -resource "aws_security_group" "allow_tls" { - name = "allow_tls" - description = "Allow TLS inbound traffic" - - ingress { - description = "TLS from World" - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "allow_tls" - } -} - - -resource "aws_security_group" "allow_ssh" { - name = "allow_ssh" - description = "Allow ssh inbound traffic" - - ingress { - description = "SSH from World" - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "allow_ssh" - } -} - -resource "aws_security_group" "allow_http" { - name = "allow_http" - description = "Allow HTTP inbound traffic" - - ingress { - description = "HTTP from World" - from_port = 80 - to_port = 80 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "allow_ssh" - } -} - - -resource "aws_security_group" "allow_jitsi_video" { - name = "allow_jitsi_video" - description = "Allow jitsi video inbound traffic" - - ingress { - description = "Jitsi Video from world" - from_port = 10000 - to_port = 10000 - protocol = "udp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "allow_jitsi_video" - } -} - -variable "public_key" { - type = string -} - -resource "aws_key_pair" "deployer" { - key_name = "deployer-key" - public_key = var.public_key -} - - - - diff --git a/infrastructure/clients/aws-example/public.tfvars b/infrastructure/clients/aws-example/public.tfvars deleted file mode 100644 index 6ed7195ec..000000000 --- a/infrastructure/clients/aws-example/public.tfvars +++ /dev/null @@ -1,2 +0,0 @@ -# Search for Zone ID on Cloudflare dashboard for the domain -cloudflare_zone_id = "211e94f01d483d1555310b9a19cf98dd" diff --git a/infrastructure/clients/aws-example/secrets-example.tfvars b/infrastructure/clients/aws-example/secrets-example.tfvars deleted file mode 100644 index ce0d29462..000000000 --- a/infrastructure/clients/aws-example/secrets-example.tfvars +++ /dev/null @@ -1,3 +0,0 @@ -cloudflare_api_key = "cloudflare_api_key" -cloudflare_email = "cloudflare_email" -public_key = "ssh public_key" diff --git a/infrastructure/clients/vultr-example/infrastructure.tf b/infrastructure/clients/vultr-example/infrastructure.tf deleted file mode 100644 index ab3fbec83..000000000 --- a/infrastructure/clients/vultr-example/infrastructure.tf +++ /dev/null @@ -1,89 +0,0 @@ -variable "public_key" { - type = string -} - -variable "cloudflare_email" { - type = string -} - -variable "cloudflare_api_key" { - type = string -} - -variable "cloudflare_zone_id" { - type = string -} - -provider "cloudflare" { - version = "~> 2.0" - email = var.cloudflare_email - api_key = var.cloudflare_api_key -} - -# Create a record -resource "cloudflare_record" "convene-test-vultr" { - zone_id = var.cloudflare_zone_id - name = "convene-test-vultr" - value = vultr_server.convene_vultr_video.main_ip - type = "A" - ttl = 1 -} - -variable "vultr_api_key" { - type = string -} - -provider "vultr" { - api_key = var.vultr_api_key -} - -variable "vultr_snapshot_id" { - type = string -} - -resource "vultr_ssh_key" "my_ssh_key" { - name = "my-ssh-key" - ssh_key = var.public_key -} - -# Create a Vultr server -resource "vultr_server" "convene_vultr_video" { - snapshot_id = var.vultr_snapshot_id - region_id = "12" - plan_id = "201" - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - ssh_key_ids = [vultr_ssh_key.my_ssh_key.id] -} - -# Create Vultr firewall group -resource "vultr_firewall_group" "convene_vultr_firewall_group" { - description = "convene_vultr_firewall_group" -} - -resource "vultr_firewall_rule" "allow_tls_convene_vultr_firewall_rule" { - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - protocol = "tcp" - network = "0.0.0.0/0" - from_port = "443" -} - -resource "vultr_firewall_rule" "allow_ssh_convene_vultr_firewall_rule" { - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - protocol = "tcp" - network = "0.0.0.0/0" - from_port = "22" -} - -resource "vultr_firewall_rule" "allow_http_convene_vultr_firewall_rule" { - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - protocol = "tcp" - network = "0.0.0.0/0" - from_port = "80" -} - -resource "vultr_firewall_rule" "allow_jitsi_video_convene_vultr_firewall_rule" { - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - protocol = "udp" - network = "0.0.0.0/0" - from_port = "10000" -} diff --git a/infrastructure/clients/vultr-example/public.tfvars b/infrastructure/clients/vultr-example/public.tfvars deleted file mode 100644 index ac5ca033b..000000000 --- a/infrastructure/clients/vultr-example/public.tfvars +++ /dev/null @@ -1,3 +0,0 @@ -# Search for Zone ID on Cloudflare dashboard for the domain -cloudflare_zone_id = "211e94f01d483d1555310b9a19cf98dd" -vultr_snapshot_id = "b765f07738a83" diff --git a/infrastructure/clients/vultr-example/secrets-example.tfvars b/infrastructure/clients/vultr-example/secrets-example.tfvars deleted file mode 100644 index 4199bf036..000000000 --- a/infrastructure/clients/vultr-example/secrets-example.tfvars +++ /dev/null @@ -1,4 +0,0 @@ -cloudflare_api_key = "cloudflare_api_key" -cloudflare_email = "cloudflare_email" -public_key = "ssh public_key" -vultr_api_key = "vultr_api_key" diff --git a/infrastructure/clients/zinc/infrastructure.tf b/infrastructure/clients/zinc/infrastructure.tf deleted file mode 100644 index 06e6e60ca..000000000 --- a/infrastructure/clients/zinc/infrastructure.tf +++ /dev/null @@ -1,120 +0,0 @@ -variable "public_key" { - type = string -} - -variable "cloudflare_email" { - type = string -} - -variable "cloudflare_api_key" { - type = string -} - -variable "cloudflare_zone_id" { - type = string -} - - -variable "vultr_api_key" { - type = string -} - -provider "cloudflare" { - version = "~> 2.0" - email = var.cloudflare_email - api_key = var.cloudflare_api_key -} - - - -# Create a DNS Record for the application instance deployed to Heroku -resource "cloudflare_record" "convene" { - zone_id = var.cloudflare_zone_id - name = "convene" - value = "concave-cougar-3i77opu3gndyc7goxubexjnz.herokudns.com" - type = "CNAME" - ttl = 1 -} - -# Create a branded-domain for the Zinc Space -resource "cloudflare_record" "meet" { - zone_id = var.cloudflare_zone_id - name = "meet" - value = "quiet-shark-e5n5v9yt13haqkprrhhjdidx.herokudns.com" - type = "CNAME" - ttl = 1 -} - -# Create a branded-domain for the Convene-demo space -resource "cloudflare_record" "convene-demo" { - zone_id = var.cloudflare_zone_id - name = "convene-demo" - value = "immense-mouse-pxnyvs9k482ckrqx11jrzf6a.herokudns.com" - type = "CNAME" - ttl = 1 -} - -provider "vultr" { - api_key = var.vultr_api_key -} - -variable "vultr_snapshot_id" { - type = string -} - -resource "vultr_ssh_key" "my_ssh_key" { - name = "my-ssh-key" - ssh_key = var.public_key -} - -# Create a Vultr server for the videobridge -resource "vultr_server" "convene_vultr_video" { - snapshot_id = var.vultr_snapshot_id - region_id = "12" - plan_id = "402" - label = "convene-videobridge-zinc.zinc.coop" - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - ssh_key_ids = [vultr_ssh_key.my_ssh_key.id] -} - -# Create a DNS record for the videobridge -resource "cloudflare_record" "convene-videobridge-zinc" { - zone_id = var.cloudflare_zone_id - name = "convene-videobridge-zinc" - value = vultr_server.convene_vultr_video.main_ip - type = "A" - ttl = 1 -} - -# Create Vultr firewall group -resource "vultr_firewall_group" "convene_vultr_firewall_group" { - description = "convene_vultr_firewall_group" -} - -resource "vultr_firewall_rule" "allow_tls_convene_vultr_firewall_rule" { - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - protocol = "tcp" - network = "0.0.0.0/0" - from_port = "443" -} - -resource "vultr_firewall_rule" "allow_ssh_convene_vultr_firewall_rule" { - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - protocol = "tcp" - network = "0.0.0.0/0" - from_port = "22" -} - -resource "vultr_firewall_rule" "allow_http_convene_vultr_firewall_rule" { - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - protocol = "tcp" - network = "0.0.0.0/0" - from_port = "80" -} - -resource "vultr_firewall_rule" "allow_jitsi_video_convene_vultr_firewall_rule" { - firewall_group_id = vultr_firewall_group.convene_vultr_firewall_group.id - protocol = "udp" - network = "0.0.0.0/0" - from_port = "10000" -} diff --git a/infrastructure/clients/zinc/public.tfvars b/infrastructure/clients/zinc/public.tfvars deleted file mode 100644 index da8e0fb1c..000000000 --- a/infrastructure/clients/zinc/public.tfvars +++ /dev/null @@ -1,2 +0,0 @@ -cloudflare_zone_id = "211e94f01d483d1555310b9a19cf98dd" -vultr_snapshot_id = "93e5f2c9afef3" diff --git a/infrastructure/clients/zinc/secrets-example.tfvars b/infrastructure/clients/zinc/secrets-example.tfvars deleted file mode 100644 index ccb692bd1..000000000 --- a/infrastructure/clients/zinc/secrets-example.tfvars +++ /dev/null @@ -1,4 +0,0 @@ -cloudflare_email = "example@example.com" -cloudflare_api_key = "get-this-from-cloudflare" -public_key = "ssh public_key" -vultr_api_key = "get-this-from-vultr" diff --git a/infrastructure/docs/aws-permissions.md b/infrastructure/docs/aws-permissions.md deleted file mode 100644 index 1ac8d4c1f..000000000 --- a/infrastructure/docs/aws-permissions.md +++ /dev/null @@ -1,50 +0,0 @@ -## AWS IAM policy for Packer - -[Minimal set permissions necessary for Packer to work](https://www.packer.io/docs/builders/amazon.html#iam-task-or-instance-role) -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "VisualEditor0", - "Effect": "Allow", - "Action": [ - "ec2:AttachVolume", - "ec2:AuthorizeSecurityGroupIngress", - "ec2:DeregisterImage", - "ec2:DeleteSnapshot", - "ec2:DescribeInstances", - "ec2:CreateKeyPair", - "ec2:DescribeRegions", - "ec2:CreateImage", - "ec2:CopyImage", - "ec2:ModifyImageAttribute", - "ec2:DescribeSnapshots", - "ec2:DeleteVolume", - "ec2:ModifySnapshotAttribute", - "ec2:CreateSecurityGroup", - "ec2:DescribeVolumes", - "ec2:CreateSnapshot", - "ec2:ModifyInstanceAttribute", - "ec2:DescribeInstanceStatus", - "ec2:DetachVolume", - "ec2:TerminateInstances", - "ec2:DescribeTags", - "ec2:CreateTags", - "ec2:RegisterImage", - "ec2:RunInstances", - "ec2:StopInstances", - "ec2:DescribeSecurityGroups", - "ec2:CreateVolume", - "ec2:DescribeImages", - "ec2:GetPasswordData", - "ec2:DescribeImageAttribute", - "ec2:DeleteSecurityGroup", - "ec2:DescribeSubnets", - "ec2:DeleteKeyPair" - ], - "Resource": "*" - } - ] -} -``` diff --git a/infrastructure/docs/operator-builds-space.png b/infrastructure/docs/operator-builds-space.png deleted file mode 100644 index e0615ac4c..000000000 Binary files a/infrastructure/docs/operator-builds-space.png and /dev/null differ diff --git a/infrastructure/features/hosting-zulip.feature b/infrastructure/features/hosting-zulip.feature deleted file mode 100644 index 9a62c5681..000000000 --- a/infrastructure/features/hosting-zulip.feature +++ /dev/null @@ -1,19 +0,0 @@ -@unscheduled -Feature: Zulip Hosting - In order to facilitate asynchronous text conversations - As an Operator - I would like to be able to host a Zulip instance for my community - - Scenario: Provisioning a single-server Zulip instance on AWS - Given AWS Access Key and Secret with the rights to provision instances - And an empty hosts inventory - And a public domain with a wildcard SSL certificate - When an Operator runs the `zulip/provision` command with: - | arguments | - | --instance-size=t3.micro | - | --public-domain={{ subdomain }}.{{domain}} | - Then a JITSI meet instance is provisioned with the following attributes: - | attribute | value | - | instance-size | t3.micro | - | accessible-via | https://{{subdomain}}.{{domain}} | - And the IP address is added to the hosts' inventory definition within the "[zulip_hosts]" group \ No newline at end of file diff --git a/infrastructure/features/space-reliability.feature b/infrastructure/features/space-reliability.feature deleted file mode 100644 index ff25f9b24..000000000 --- a/infrastructure/features/space-reliability.feature +++ /dev/null @@ -1,17 +0,0 @@ -Feature: Space Reliability - In order to feel confident that my Space will be available whenever I need it - I want a robust set of structures to ensure reliability - - - Scenario: Nightly restarts - Given a Client Space is provisioned - When it becomes Midnight in the Client's timezone - Then the Client Space is rebooted - - Scenario: Multiple Operators may sign in to Provisioned Convene Instances - Given a running Convene instance that was launched from a packer image with the following ssh authorized keys: - | user | key | - | zee | https://github.com/zspencer.keys | - | tomlee | https://github.com/user512.keys | - When zee uses ssh to connects to the running instance using zee's private key - Then zee is logged into the running instance diff --git a/infrastructure/features/video-spaces.feature b/infrastructure/features/video-spaces.feature deleted file mode 100644 index d9577b76b..000000000 --- a/infrastructure/features/video-spaces.feature +++ /dev/null @@ -1,35 +0,0 @@ -Feature: Video Spaces - In order discuss things face-to-face within my organization - As Colin Collaborator and Felicia Faciliator - I want a Video Space - - Scenario: Operator Builds an 8 person Video Space on AWS - When an Operator runs the `videobridge/build` command with: - | arguments | - | --region=us-west-1 | - | --provider=aws | - | --client={{client}} | - Then a convene-videobridge-{{client}} AMI is available within the us-west-1 region - - Scenario: Operator Provisions an 8 person Video Space on AWS - Given an Operator has ran `videobridge/build` for {{client}} - When an Operator runs the `videobridge/provision` command with: - | arguments | - | --client={{client}} | - Then a JITSI meet instance is available at https://convene-videobridge-{{client}}.zinc.coop - - Scenario: Operator Builds an 8 person Video Space on Vultr - When an Operator runs the `videobridge/build` command with: - | arguments | - | --region=12 | - | --provider=vultr | - | --client={{client}} | - Then a convene-videobridge-{{client}} is available within region 12 (Silcon Valley) - - Scenario: Operator Provisions an 8 person Video Space on Vultr and specifiy ssh username - Given an Operator has ran `videobridge/build` for {{client}} - When an Operator runs the `videobridge/provision` command with: - | arguments | - | --client={{client}} | - | --ssh-username=root | - Then a JITSI meet instance is available at https://convene-videobridge-{{client}}.zinc.coop diff --git a/infrastructure/jitsi-meet-local/README.md b/infrastructure/jitsi-meet-local/README.md deleted file mode 100644 index 8a6b3f779..000000000 --- a/infrastructure/jitsi-meet-local/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Local Infrastructure - -- [Running Jitsi Meet locally](#running-jitsi-meet-locally) -- [Debugging your local Jitsi](#debugging-your-local-jitsi) -- [Docker configuration](#docker-configuration) - -This directory provides a Dockerized configuration for running Jitsi -locally, for when you need to work on Jitsi configuration or debugging. - -## Running Jitsi Meet locally - -You will need a running Docker engine. See the official Docker documentation -for instructions for your specific platform: https://docs.docker.com/engine/install/ - -To build and run a local container with Jitsi, run (from repo root): -``` -$ bin/jitsi-local-run -``` - -This configuration uses a self-signed certificate, so when accessing your local -https://jitsi you will need to bypass your browser's security warnings. (You -might need to use Firefox for this to work, Chrome seems to have tightened -their settings to a point where you can't bypass this warning.) - -The services running in the container are fronted by an Nginx instance that relies on the -hostname in order to route you to the correct service, so you will need to always access -the local services via the hostname `jitsi`, and not just the Docker IP address. For this -to work, you will need to add the your Docker IP as hostname `jitsi` to you `/etc/hosts` file. - -## Debugging your local Jitsi - -You can interact with your local Jitsi Meet by starting a shell within the container: -``` -$ docker exec -it jitsi-meet-local bash -``` - -You are now root within the Jitsi Meet container. Here you can: -* Access Jitsi's configuration files in `/etc/jitsi/*` -* See the videobridge logs: `more /var/log/jitsi/jvb.log` -* Query the videobridge's debug endpoint: `curl localhost:8080/debug` - -For more docs on debugging Jitsi's videobridge, see https://github.com/jitsi/jitsi-videobridge/blob/master/doc/debugging.md - -## Docker configuration - -The "entry point" for this Docker configuration is the -[`jitsi-meet.Dockerfile`](jitsi-meet.Dockerfile), which specifies how to -build a Docker image for a local Jitsi setup. This Dockerfile depends, in -turn, on the shell scripts in this directory. diff --git a/infrastructure/jitsi-meet-local/install-jitsi-meet.sh b/infrastructure/jitsi-meet-local/install-jitsi-meet.sh deleted file mode 100755 index 74fb99956..000000000 --- a/infrastructure/jitsi-meet-local/install-jitsi-meet.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -set -e - -# Script assumes it is running as root -# -# Jitsi installation steps were cobbled together from: -# - Jitsi self-hosting docs: https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart -# - forum tips about how to silently install jitsi-meet: https://community.jitsi.org/t/silent-installation/55519 -# To see how we install Jitsi in production, see the install script in this repo: infrastructure/videobridge/install - -# To Build docker image: -# $ docker build -f jitsi-meet.Dockerfile . -# Docker run command with published ports: -# $ docker run -it -p 80:80 -p 443:443 -p 8080:8080 --hostname jitsi -# Verify you have a running videobridge: -# $ curl localhost:8080/about/version - -apt-get update && apt-get install -y curl gpg debconf-utils nginx -curl https://download.jitsi.org/jitsi-key.gpg.key | sh -c 'gpg --dearmor > /usr/share/keyrings/jitsi-keyring.gpg' -echo 'deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/' | tee /etc/apt/sources.list.d/jitsi-stable.list > /dev/null - -HOSTNAME="jitsi" -cat << EOF | debconf-set-selections -jicofo jitsi-videobridge/jvb-hostname string $HOSTNAME -jitsi-meet-prosody jitsi-meet-prosody/jvb-hostname string $HOSTNAME -jitsi-meet-prosody jitsi-videobridge/jvb-hostname string $HOSTNAME -jitsi-meet-turnserver jitsi-videobridge/jvb-hostname string $HOSTNAME -jitsi-meet-web-config jitsi-videobridge/jvb-hostname string $HOSTNAME -jitsi-videobridge2 jitsi-videobridge/jvb-hostname string $HOSTNAME -jitsi-meet jitsi-meet/cert-choice select Generate a new self-signed certificate -EOF - -debconf-get-selections | grep jitsi - -export DEBIAN_FRONTEND=noninteractive -apt-get update && apt-get install -y jitsi-meet diff --git a/infrastructure/jitsi-meet-local/jitsi-meet.Dockerfile b/infrastructure/jitsi-meet-local/jitsi-meet.Dockerfile deleted file mode 100644 index 61d808064..000000000 --- a/infrastructure/jitsi-meet-local/jitsi-meet.Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM ubuntu:focal - -COPY *.sh / -RUN /install-jitsi-meet.sh - -EXPOSE 80 443 8080 - -CMD /run-jitsi-services.sh diff --git a/infrastructure/jitsi-meet-local/run-jitsi-services.sh b/infrastructure/jitsi-meet-local/run-jitsi-services.sh deleted file mode 100755 index 71ad8f043..000000000 --- a/infrastructure/jitsi-meet-local/run-jitsi-services.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -# This script assumes it is running as root, and is meant for use as entrypoint in a Docker container. - -set -e - -# Make sure all the jitsi-related services are running -# In the case that existing .pid files are found, 'restart' works more reliably than using 'start'. -for service in jicofo jitsi-videobridge2 prosody nginx ; do service $service restart ; done - -# Cheesy way to prevent this script from ever exiting. -# -# This is needed because the various jitsi servers are being as background -# services, and Docker wants and entrypoint that doesn't exit (when the -# entrypoint exits, the container will stop). -# -# Would be nice to polish this, but since it is for development debugging, it -# might not be worth the investment. -sleep infinity diff --git a/infrastructure/operators.yml b/infrastructure/operators.yml deleted file mode 100644 index beddac644..000000000 --- a/infrastructure/operators.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -# This is provided by the Packer Ansible provisioner -# https://www.packer.io/docs/provisioners/ansible.html#host_alias -- hosts: default - vars: - users: - - username: tomlee - shell: /bin/bash - github: user512 - - username: zee - shell: /bin/bash - github: zspencer - - become: yes - become_method: sudo - tasks: - - name: "ensure sudoers dont need to put in a password" - lineinfile: - path: /etc/sudoers - regexp: '^%sudo ALL=' - line: '%sudo ALL=(ALL:ALL) NOPASSWD:ALL' - - - name: Create users - with_items: "{{ users }}" - user: name={{ item.username }} shell={{ item.shell }} groups=sudo state=present - - name: "Set authorized key" - with_items: "{{ users }}" - authorized_key: user={{ item.username }} key=https://github.com/{{ item.github }}.keys exclusive=yes state=present diff --git a/infrastructure/videobridge/aws.json b/infrastructure/videobridge/aws.json deleted file mode 100644 index 3efd96705..000000000 --- a/infrastructure/videobridge/aws.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "variables": { - "aws_access_key": "{{env `AWS_ACCESS_KEY`}}", - "aws_secret_key": "{{env `AWS_SECRET_KEY`}}", - "videobridge_domain": "{{env `VIDEOBRIDGE_DOMAIN`}}", - "instance_type": "t2.micro", - "region": "{{env `REGION`}}" - }, - "builders": [{ - "type": "amazon-ebs", - "access_key": "{{user `aws_access_key`}}", - "secret_key": "{{user `aws_secret_key`}}", - "region": "{{user `region`}}", - "source_ami_filter": { - "filters": { - "virtualization-type": "hvm", - "name": "ubuntu/images/*ubuntu-focal-20.04-amd64-server-*", - "root-device-type": "ebs" - }, - "owners": ["099720109477"], - "most_recent": true - }, - "instance_type": "{{user `instance_type`}}", - "ssh_username": "ubuntu", - "ami_name": "{{user `videobridge_domain`}} {{timestamp}}" - }], - "provisioners": [{ - "environment_vars": [ - "VIDEOBRIDGE_DOMAIN={{ user `videobridge_domain` }}" - ], - "type": "shell", - "script": "videobridge/install" - }, - { - "type": "ansible", - "__comment": [ - "Ensure we are using the default user created by AWS", - "https://www.packer.io/docs/provisioners/ansible#user" - ], - "user": "ubuntu", - "playbook_file": "operators.yml" - }] -} diff --git a/infrastructure/videobridge/build b/infrastructure/videobridge/build deleted file mode 100755 index 00e446479..000000000 --- a/infrastructure/videobridge/build +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -for i in "$@" -do -case $i in - --client=*) - CLIENT="${i#*=}" - shift - ;; - --videobridge-domain=*) - VIDEOBRIDGE_DOMAIN="${i#*=}" - shift - ;; - --region=*) - REGION="${i#*=}" - shift - ;; - --provider=*) - PROVIDER="${i#*=}" - shift - ;; -esac -done - - -if [ -z ${VIDEOBRIDGE_DOMAIN+x} ]; -then - VIDEOBRIDGE_DOMAIN="convene-videobridge-$CLIENT.zinc.coop" -fi -echo $VIDEOBRIDGE_DOMAIN - -# Automated: Build AMI -packer build \ - -var "videobridge_domain=${VIDEOBRIDGE_DOMAIN}" \ - -var "region=${REGION}"\ - videobridge/${PROVIDER}.json - - diff --git a/infrastructure/videobridge/install b/infrastructure/videobridge/install deleted file mode 100755 index 3aa4a16d1..000000000 --- a/infrastructure/videobridge/install +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -# Note: The sleep 30 is very important. -# Because Packer is able to detect and SSH into the instance as soon as SSH is available, -# Ubuntu actually doesn't get proper amounts of time to initialize. -# The sleep makes sure that the OS properly initializes. -# https://www.packer.io/intro/getting-started/provision.html#configuring-provisioners -sleep 30 -set +o +x - -echo 'deb https://download.jitsi.org stable/' | sudo tee -a /etc/apt/sources.list.d/jitsi-stable.list -wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add - -sudo apt-add-repository universe -sudo apt-get update -sudo apt-get -y install debconf-utils nginx-full - -# We pipe a single command at a time into debconf-set-selections to configure -# See `man debconf-set-selections` -echo jitsi-videobridge jitsi-videobridge/jvb-hostname string $VIDEOBRIDGE_DOMAIN | sudo debconf-set-selections -echo jitsi-meet-prosody jitsi-videobridge/jvb-hostname string $VIDEOBRIDGE_DOMAIN | sudo debconf-set-selections -echo "jitsi-meet-web-config jitsi-meet/cert-choice select Generate a new self-signed certificate (You will later get a chance to obtain a Let's encrypt certificate)" | sudo debconf-set-selections -echo jitsi-meet-web-config jitsi-meet/cert-path-crt string /etc/ssl/$VIDEOBRIDGE_DOMAIN.crt | sudo debconf-set-selections -echo jitsi-meet-web-config jitsi-meet/cert-path-key string /etc/ssl/$VIDEOBRIDGE_DOMAIN.key | sudo debconf-set-selections - -sudo apt-get -y install jitsi-meet -sudo rm /usr/share/jitsi-meet/images/watermark.png -# Change Jitsi Meet branding to Convene -# Ref: https://community.jitsi.org/t/app-name-doesnt-have-effect/71648/2 -sudo sed -i "s/Jitsi Meet/Convene/" /usr/share/jitsi-meet/interface_config.js - -# Restart instance every PST midnight -sudo crontab -l > mycron -echo "0 7 * * * /usr/sbin/shutdown -r now" >> mycron -sudo crontab mycron -rm mycron diff --git a/infrastructure/videobridge/install-letsencrypt-cert.sh b/infrastructure/videobridge/install-letsencrypt-cert.sh deleted file mode 100755 index 776e095b8..000000000 --- a/infrastructure/videobridge/install-letsencrypt-cert.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash - -set -e - -DEB_CONF_RESULT=`debconf-show jitsi-meet-web-config | grep jvb-hostname` -DOMAIN="${DEB_CONF_RESULT##*:}" -# remove whitespace -DOMAIN="$(echo -e "${DOMAIN}" | tr -d '[:space:]')" - -echo "-------------------------------------------------------------------------" -echo "This script will:" -echo "- Need a working DNS record pointing to this machine(for domain ${DOMAIN})" -echo "- Download certbot from https://dl.eff.org to /usr/local/sbin" -echo "- Install additional dependencies in order to request Let’s Encrypt certificate" -echo "- If running with jetty serving web content, will stop Jitsi Videobridge" -echo "- Configure and reload nginx or apache2, whichever is used" -echo "- Configure the coturn server to use Let's Encrypt certificate and add required deploy hooks" -echo "- Add command in weekly cron job to renew certificates regularly" -echo "" -echo "You need to agree to the ACME server's Subscriber Agreement (https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf) " -echo "by providing an email address for important account notifications" - -EMAIL="operations+convene@zinc.coop" - -cd /usr/local/sbin - -if command -v certbot >/dev/null 2>&1; then - echo "we good" -else - sudo apt-get update - sudo apt-get -y install software-properties-common certbot -fi - -CRON_FILE="/etc/cron.weekly/letsencrypt-renew" -if [ ! -d "/etc/cron.weekly" ] ; then - mkdir "/etc/cron.weekly" -fi -echo "#!/bin/bash" > $CRON_FILE -echo "/usr/local/sbin/certbot renew >> /var/log/le-renew.log" >> $CRON_FILE - -CERT_KEY="/etc/letsencrypt/live/$DOMAIN/privkey.pem" -CERT_CRT="/etc/letsencrypt/live/$DOMAIN/fullchain.pem" - -if [ -f /etc/nginx/sites-enabled/$DOMAIN.conf ] ; then - - TURN_CONFIG="/etc/turnserver.conf" - TURN_HOOK=/etc/letsencrypt/renewal-hooks/deploy/0000-coturn-certbot-deploy.sh - if [ -f $TURN_CONFIG ] && grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then - mkdir -p $(dirname $TURN_HOOK) - - cp /usr/share/jitsi-meet-turnserver/coturn-certbot-deploy.sh $TURN_HOOK - chmod u+x $TURN_HOOK - sed -i "s/jitsi-meet.example.com/$DOMAIN/g" $TURN_HOOK - - certbot certonly --noninteractive \ - --webroot --webroot-path /usr/share/jitsi-meet \ - -d $DOMAIN \ - --agree-tos --email $EMAIL \ - --deploy-hook $TURN_HOOK - else - certbot certonly --noninteractive \ - --webroot --webroot-path /usr/share/jitsi-meet \ - -d $DOMAIN \ - --agree-tos --email $EMAIL - fi - - echo "Configuring nginx" - - CONF_FILE="/etc/nginx/sites-available/$DOMAIN.conf" - CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g') - CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g') - sed -i "s/ssl_certificate_key\ \/etc\/jitsi\/meet\/.*key/ssl_certificate_key\ $CERT_KEY_ESC/g" \ - $CONF_FILE - CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g') - CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g') - sed -i "s/ssl_certificate\ \/etc\/jitsi\/meet\/.*crt/ssl_certificate\ $CERT_CRT_ESC/g" \ - $CONF_FILE - - echo "service nginx reload" >> $CRON_FILE - service nginx reload -elif [ -f /etc/apache2/sites-enabled/$DOMAIN.conf ] ; then - - certbot certonly --noninteractive \ - --webroot --webroot-path /usr/share/jitsi-meet \ - -d $DOMAIN \ - --agree-tos --email $EMAIL - - echo "Configuring apache2" - - CONF_FILE="/etc/apache2/sites-available/$DOMAIN.conf" - CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g') - CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g') - sed -i "s/SSLCertificateKeyFile\ \/etc\/jitsi\/meet\/.*key/SSLCertificateKeyFile\ $CERT_KEY_ESC/g" \ - $CONF_FILE - CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g') - CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g') - sed -i "s/SSLCertificateFile\ \/etc\/jitsi\/meet\/.*crt/SSLCertificateFile\ $CERT_CRT_ESC/g" \ - $CONF_FILE - - echo "service apache2 reload" >> $CRON_FILE - service apache2 reload -fi - -# the cron file that will renew certificates -chmod a+x $CRON_FILE diff --git a/infrastructure/videobridge/provision b/infrastructure/videobridge/provision deleted file mode 100755 index a8ebf26f8..000000000 --- a/infrastructure/videobridge/provision +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -SSH_USERNAME='ubuntu' -for i in "$@" -do -case $i in - --client=*) - CLIENT="${i#*=}" - shift - ;; - --videobridge-domain=*) - VIDEOBRIDGE_DOMAIN="${i#*=}" - shift - ;; - --flush-dns-cache) - FLUSH_DNS_CACHE=YES - shift - ;; - --ssh-username=*) - SSH_USERNAME="${i#*=}" - shift - ;; -esac -done - -if [ -z ${VIDEOBRIDGE_DOMAIN+x} ]; -then - VIDEOBRIDGE_DOMAIN="convene-videobridge-$CLIENT.zinc.coop" -fi -echo $VIDEOBRIDGE_DOMAIN - -# TODO: Figure out how to share the secrets safely and the terraform.tstate -# (push/pull from private bucket? Spin up a consul instance?) -(cd clients/$CLIENT && terraform init && - terraform apply -var-file public.tfvars -var-file secrets.tfvars) - -# Push the certbot install script that works for Ubuntu 20.04 to the server -if [ $FLUSH_DNS_CACHE ]; then - echo "Flushing DNS cache" - sudo killall -HUP mDNSResponder -fi -echo $VIDEOBRIDGE_DOMAIN -scp videobridge/install-letsencrypt-cert.sh $SSH_USERNAME@$VIDEOBRIDGE_DOMAIN: -ssh -t $SSH_USERNAME@$VIDEOBRIDGE_DOMAIN 'sudo ./install-letsencrypt-cert.sh' \ No newline at end of file diff --git a/infrastructure/videobridge/vultr.json b/infrastructure/videobridge/vultr.json deleted file mode 100644 index 161c5327b..000000000 --- a/infrastructure/videobridge/vultr.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "variables": { - "vultr_api_key": "{{env `VULTR_API_KEY`}}", - "videobridge_domain": "{{env `VIDEOBRIDGE_DOMAIN`}}", - "instance_type": "201", - "region": "{{env `REGION`}}" - }, - "builders": [ - { - "type": "vultr", - "api_key": "{{user `vultr_api_key`}}", - "snapshot_description": "{{user `videobridge_domain`}} {{timestamp}}", - "region_id": "{{user `region`}}", - "plan_id": "{{user `instance_type`}}", - "os_id": "387", - "ssh_username": "root", - "state_timeout": "10m" - } - ], - "provisioners": [{ - "environment_vars": [ - "VIDEOBRIDGE_DOMAIN={{ user `videobridge_domain` }}" - ], - "type": "shell", - "script": "videobridge/install" - }, - { - "type": "ansible", - "playbook_file": "operators.yml" - }] -} diff --git a/spec/factories/utility_hookup.rb b/spec/factories/utility_hookup.rb index 6ec5cca7e..2d1952a26 100644 --- a/spec/factories/utility_hookup.rb +++ b/spec/factories/utility_hookup.rb @@ -4,8 +4,8 @@ association(:space) utility_slug { "null" } - trait :jitsi do - utility_slug { "jitsi" } + trait :stripe do + utility_slug { "stripe" } end end end diff --git a/spec/models/demo_space_spec.rb b/spec/models/demo_space_spec.rb index 80ae64019..6ec904c9e 100644 --- a/spec/models/demo_space_spec.rb +++ b/spec/models/demo_space_spec.rb @@ -11,7 +11,6 @@ expect(demo_space).to be_persisted expect(demo_space.name).to eql("Convene Demo") expect(demo_space.slug).to eql("convene-demo") - expect(demo_space.jitsi_meet_domain).to eql("convene-videobridge-zinc.zinc.coop") expect(demo_space.branded_domain).to eql("convene-demo.zinc.coop") expect(demo_space.rooms.find_by(name: "Zee's Desk")).to be_present diff --git a/spec/models/space/factory_spec.rb b/spec/models/space/factory_spec.rb index acdb278b3..a38350d05 100644 --- a/spec/models/space/factory_spec.rb +++ b/spec/models/space/factory_spec.rb @@ -29,7 +29,6 @@ blueprint: :system_test)) expect(space.rooms).to be_present - expect(space.utility_hookups).to be_present end end end diff --git a/spec/models/utility_hookup_spec.rb b/spec/models/utility_hookup_spec.rb index d9c51341a..341b7781a 100644 --- a/spec/models/utility_hookup_spec.rb +++ b/spec/models/utility_hookup_spec.rb @@ -7,8 +7,8 @@ describe ".new" do it "accepts nested attributes for the utility" do - uh = UtilityHookup.new(utility_slug: :jitsi, utility_attributes: {meet_domain: "asdf"}) - expect(uh.utility.meet_domain).to eq("asdf") + uh = UtilityHookup.new(utility_slug: :stripe, utility_attributes: {api_token: "asdf"}) + expect(uh.utility.api_token).to eq("asdf") end end @@ -29,7 +29,7 @@ describe "#configuration" do it "starts as an empty hash" do - uh = FactoryBot.create(:utility_hookup, :jitsi) + uh = FactoryBot.create(:utility_hookup, :stripe) expect(uh.configuration).to eq({}) end diff --git a/spec/requests/spaces_controller_request_spec.rb b/spec/requests/spaces_controller_request_spec.rb index 090771248..e460c9fb3 100644 --- a/spec/requests/spaces_controller_request_spec.rb +++ b/spec/requests/spaces_controller_request_spec.rb @@ -62,7 +62,6 @@ space = Space.find_by(name: attributes[:name]) expect(space.rooms).not_to be_empty expect(space.memberships).not_to be_empty - expect(space.utility_hookups).not_to be_empty end end end diff --git a/spec/requests/utility_hookups_controller_request_spec.rb b/spec/requests/utility_hookups_controller_request_spec.rb index e127df3dc..e6c7028a0 100644 --- a/spec/requests/utility_hookups_controller_request_spec.rb +++ b/spec/requests/utility_hookups_controller_request_spec.rb @@ -6,7 +6,7 @@ RSpec.describe UtilityHookupsController do let(:space) { create(:space, :with_members) } let(:utility_hookup_attributes) do - attributes_for(:utility_hookup, :jitsi).merge(utility_attributes: {"meet_domain" => "meet.example.com"}) + attributes_for(:utility_hookup, :stripe).merge(utility_attributes: { "api_token" => "fake-token" }) end let(:utility_hookup) { create(:utility_hookup, space: space) } @@ -88,7 +88,7 @@ .to(change { space.utility_hookups.count }.by(1)) expect(response).to redirect_to [:edit, space] - expect(space.utility_hookups.last.utility_slug).to eql("jitsi") + expect(space.utility_hookups.last.utility_slug).to eql("stripe") expect(space.utility_hookups.last.utility.configuration).to eq(utility_hookup_attributes[:utility_attributes]) end end diff --git a/webpack.config.js b/webpack.config.js index ff6a1298d..02844ba5a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,8 +8,7 @@ const __dirname = path.dirname(__filename); export const mode = "production"; export const devtool = "source-map"; export const entry = { - application: "./app/javascript/application.js", - furniture_video_bridge: "./app/furniture/video_bridge/index.js" + application: "./app/javascript/application.js" }; export const output = { filename: "[name].js",