Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plural Cloud CRUD #1328

Merged
merged 6 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 0 additions & 40 deletions .github/workflows/daily.yml

This file was deleted.

23 changes: 0 additions & 23 deletions .github/workflows/firebase-hosting-pull-request.yml

This file was deleted.

1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ jobs:
curl -sL 'https://github.com/pluralsh/plural-cli/releases/download/v0.5.18/plural-cli_0.5.18_Linux_amd64.tar.gz' | tar xzvf -
chmod +x plural
cp plural /usr/local/bin/plural
- run: make install-cockroach
- run: make testup
- name: Restore dependencies cache
uses: actions/cache@v3
Expand Down
76 changes: 38 additions & 38 deletions .github/workflows/www.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,41 +136,41 @@ jobs:
node-version: ${{ steps.engines.outputs.nodeVersion }}
- run: yarn --immutable
- run: yarn lint
e2e:
name: End-to-end test
runs-on: ubuntu-20.04
env:
CYPRESS_EMAIL: ${{ secrets.CYPRESS_EMAIL }}
CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }}
defaults:
run:
shell: bash
working-directory: www
steps:
- name: 'Checkout'
uses: actions/checkout@v3
- name: Read Node.js version from package.json
run: echo ::set-output name=nodeVersion::$(node -p "require('./package.json').engines.node")
id: engines
- name: 'Setup Node'
uses: actions/setup-node@v3
with:
node-version: ${{ steps.engines.outputs.nodeVersion }}
- run: yarn # Should run the --immutable in the CI by default
- run: cd e2e && yarn
- run: yarn e2e
- uses: 8398a7/action-slack@v3
if: failure()
with:
status: ${{ job.status }}
fields: workflow,repo,commit,author,pullRequest
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CYPRESS_WEBHOOK }}
- name: Upload Screenshots and Videos to Slack
if: failure()
uses: trymbill/[email protected]
with:
token: ${{ secrets.SLACK_CYPRESS_TOKEN }}
workdir: www/e2e/cypress
channels: cypress-artifacts
message-text: "See the attached videos and screenshots for more information."
# e2e:
# name: End-to-end test
# runs-on: ubuntu-20.04
# env:
# CYPRESS_EMAIL: ${{ secrets.CYPRESS_EMAIL }}
# CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }}
# defaults:
# run:
# shell: bash
# working-directory: www
# steps:
# - name: 'Checkout'
# uses: actions/checkout@v3
# - name: Read Node.js version from package.json
# run: echo ::set-output name=nodeVersion::$(node -p "require('./package.json').engines.node")
# id: engines
# - name: 'Setup Node'
# uses: actions/setup-node@v3
# with:
# node-version: ${{ steps.engines.outputs.nodeVersion }}
# - run: yarn # Should run the --immutable in the CI by default
# - run: cd e2e && yarn
# - run: yarn e2e
# - uses: 8398a7/action-slack@v3
# if: failure()
# with:
# status: ${{ job.status }}
# fields: workflow,repo,commit,author,pullRequest
# env:
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CYPRESS_WEBHOOK }}
# - name: Upload Screenshots and Videos to Slack
# if: failure()
# uses: trymbill/[email protected]
# with:
# token: ${{ secrets.SLACK_CYPRESS_TOKEN }}
# workdir: www/e2e/cypress
# channels: cypress-artifacts
# message-text: "See the attached videos and screenshots for more information."
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,7 @@ yarn-error.log*
cert.pem
key.pem


/test-certs/

.vscode
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
erlang 24.3.4.14
elixir 1.12.3
erlang 24.3.4.17
elixir 1.13.4
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM bitwalker/alpine-elixir:1.12.3 AS builder
FROM bitwalker/alpine-elixir:1.13.4 AS builder

# The following are build arguments used to change variable parts of the image.
# The name of your application/release (required)
Expand Down
22 changes: 19 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ DKR_HOST ?= dkr.plural.sh
dep ?= forge-core
GIT_COMMIT ?= abe123
TARGETARCH ?= amd64
COCKROACH_VSN ?= v24.1.3

help:
@perl -nle'print $& if m{^[a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
Expand Down Expand Up @@ -48,11 +49,26 @@ else
docker push $(DKR_HOST)/plural/${APP_NAME}:$(APP_VSN)
endif

testup: ## sets up dependent services for test
docker-compose up -d
install-cockroach:
sudo curl https://binaries.cockroachdb.com/cockroach-$(COCKROACH_VSN).linux-amd64.tgz | tar -xz && \
sudo cp -i cockroach-$(COCKROACH_VSN).linux-amd64/cockroach /usr/local/bin/ && \
sudo mkdir -p /usr/local/lib/cockroach && \
sudo cp -i cockroach-$(COCKROACH_VSN).linux-amd64/lib/libgeos.so /usr/local/lib/cockroach/ && \
sudo cp -i cockroach-$(COCKROACH_VSN).linux-amd64/lib/libgeos_c.so /usr/local/lib/cockroach/ && \
cockroach version

test-certs:
mkdir test-certs && \
cockroach cert create-ca --certs-dir test-certs --ca-key test-certs/ca.key && \
cockroach cert create-node localhost 127.0.0.1 --certs-dir test-certs --ca-key test-certs/ca.key && \
cockroach cert create-client root --certs-dir test-certs --ca-key test-certs/ca.key && \
cockroach cert list --certs-dir test-certs

testup: test-certs ## sets up dependent services for test
docker compose up -d

testdown: ## tear down test dependencies
docker-compose down
docker compose down

connectdb: ## proxies the db in kubernetes via kubectl
@echo "run psql -U forge -h 127.0.0.1 forge to connect"
Expand Down
96 changes: 96 additions & 0 deletions apps/core/lib/core/clients/console.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
defmodule Core.Clients.Console do
require Logger

@clusters_q """
query {
clusters(first: 100) {
edges { node { name id distro metadata } }
}
}
"""

@create_svc_q """
mutation Create($clusterId: ID!, $attributes: ServiceDeploymentAttributes!) {
createServiceDeployment(clusterId: $clusterId, attributes: $attributes) {
id
}
}
"""

@delete_svc_q """
mutation Delete($id: ID!) {
deleteServiceDeployment(id: $id) {
id
}
}
"""

@update_svc_q """
mutation Update($id: ID!, $attributes: ServiceUpdateAttributes!) {
updateServiceDeployment(id: $id) {
id
}
}
"""

@repo_q """
query Repo($url: String!) {
gitRepository(url: $url) {
id
}
}
"""

def new(url, token) do
Req.new(base_url: url, auth: "Token #{token}")
|> AbsintheClient.attach()
end

def clusters(client) do
Req.post(client, graphql: @clusters_q)
|> case do
{:ok, %Req.Response{body: %{"clusters" => %{"edges" => edges}}}} -> {:ok, Enum.map(edges, & &1["node"])}
res ->
Logger.warn "Failed to fetch clusters: #{inspect(res)}"
{:error, "could not fetch clusters"}
end
end

def repo(client, url) do
Req.post(client, graphql: {@repo_q, %{url: url}})
|> case do
{:ok, %Req.Response{body: %{"gitRepository" => %{"id" => id}}}} -> {:ok, id}
res ->
Logger.warn "Failed to fetch clusters: #{inspect(res)}"
{:error, "could not fetch repo"}
end
end

def create_service(client, cluster_id, attrs) do
Req.post(client, graphql: {@create_svc_q, %{clusterId: cluster_id, attributes: attrs}})
|> service_resp("createServiceDeployment")
end

def update_service(client, id, attrs) do
Req.post(client, graphql: {@update_svc_q, %{id: id, attributes: attrs}})
|> service_resp("updateServiceDeployment")
end

def delete_service(client, id) do
Req.post(client, graphql: {@delete_svc_q, %{id: id}})
|> service_resp("deleteServiceDeployment")
end

defp service_resp({:ok, %Req.Response{status: 200, body: body}}, field) do
case body[field] do
%{"id" => id} -> {:ok, id}
err ->
Logger.warn "invalid console gql response: #{inspect(err)}"
end
end

defp service_resp(resp, _) do
Logger.error "failed to fetch from console: #{inspect(resp)}"
{:error, "console error"}
end
end
2 changes: 2 additions & 0 deletions apps/core/lib/core/conduit/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ defmodule Core.Conduit.Base do
defqueue "plural.upgrade"
defqueue "plural.scan"
defqueue "plural.cluster"
defqueue "plural.cloud"
end

pipeline :out_tracking do
Expand All @@ -36,6 +37,7 @@ defmodule Core.Conduit.Base do
publish :upgrade, exchange: "plural.topic", to: "plural.upgrade"
publish :scan, exchange: "plural.topic", to: "plural.scan"
publish :cluster, exchange: "plural.topic", to: "plural.cluster"
publish :cloud, exchange: "plural.topic", to: "plural.cloud"
end

outgoing do
Expand Down
16 changes: 16 additions & 0 deletions apps/core/lib/core/policies/cloud.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Core.Policies.Cloud do
use Piazza.Policy
alias Core.Schema.{User, ConsoleInstance}
alias Core.Services.Payments

def can?(%User{} = user, %ConsoleInstance{}, :create) do
case Payments.has_feature?(user, :cd) do
true -> :pass
_ -> {:error, "you must be on a paid plan to use Plural Cloud"}
end
end

def can?(u, %Ecto.Changeset{} = cs, action), do: can?(u, apply_changes(cs), action)

def can?(_, _, _), do: :pass
end
5 changes: 5 additions & 0 deletions apps/core/lib/core/pubsub/events.ex
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,8 @@ defmodule Core.PubSub.ClusterDependencyCreated, do: use Piazza.PubSub.Event
defmodule Core.PubSub.DeferredUpdateCreated, do: use Piazza.PubSub.Event

defmodule Core.PubSub.UpgradesPromoted, do: use Piazza.PubSub.Event

defmodule Core.PubSub.ConsoleInstanceCreated, do: use Piazza.PubSub.Event
defmodule Core.PubSub.ConsoleInstanceUpdated, do: use Piazza.PubSub.Event
defmodule Core.PubSub.ConsoleInstanceDeleted, do: use Piazza.PubSub.Event
defmodule Core.PubSub.ConsoleInstanceReaped, do: use Piazza.PubSub.Event
11 changes: 11 additions & 0 deletions apps/core/lib/core/pubsub/protocols/fanout.ex
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,14 @@ defimpl Core.PubSub.Fanout, for: [Core.PubSub.RoleCreated, Core.PubSub.RoleUpdat
|> Enum.count()
end
end

defimpl Core.PubSub.Fanout, for: [
Core.PubSub.ConsoleInstanceCreated,
Core.PubSub.ConsoleInstanceUpdated,
Core.PubSub.ConsoleInstanceDeleted
] do
def fanout(event) do
%Conduit.Message{body: event}
|> Core.Conduit.Broker.publish(:cloud)
end
end
Loading
Loading