Merge branch 'master'

This commit is contained in:
Radon Rosborough 2022-12-29 19:55:15 -07:00
commit 1aed40f7eb
39 changed files with 6754 additions and 52 deletions

6
.gitignore vendored
View File

@ -1,12 +1,14 @@
*.log
*.out
*.out.*
*.pem
.env
.lsp-repl-history
.terraform
bin
build
env.yaml
node_modules
out
sentinel.h
financials/????-??/*
!financials/????-??/breakdown.txt
agent/agent

8
agent/go.mod Normal file
View File

@ -0,0 +1,8 @@
module github.com/radian-software/riju/agent
go 1.18
require (
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
)

4
agent/go.sum Normal file
View File

@ -0,0 +1,4 @@
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=

30
agent/logging.go Normal file
View File

@ -0,0 +1,30 @@
package main
import (
"fmt"
"io"
"log"
)
func logWarn(err error) {
log.Println(err.Error())
}
func logWarnf(format string, arg ...interface{}) {
logWarn(fmt.Errorf(format, arg...))
}
func logError(err error) {
log.Println(err.Error())
}
func logErrorf(format string, arg ...interface{}) {
logError(fmt.Errorf(format, arg...))
}
func tryClose(obj io.Closer, objName string) {
err := obj.Close()
if err != nil {
logErrorf("error closing %s: %w", objName, err)
}
}

225
agent/main.go Normal file
View File

@ -0,0 +1,225 @@
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"os/exec"
"time"
"github.com/google/shlex"
"github.com/gorilla/websocket"
)
type clientMessage struct {
// "stdin"
Event string `json:"event"`
// contents of stdin
Data []byte `json:"data,omitempty"`
}
type serverMessage struct {
// "start", "stdout", "stderr", "exit", "warn", "error"
Event string `json:"event"`
// contents of stdout/stderr
Data []byte `json:"data,omitempty"`
// error message
Text string `json:"text,omitempty"`
// exit status
ExitStatus *int `json:"exitStatus,omitempty"`
}
var upgrader = websocket.Upgrader{}
func closeWs(ms *ManagedWebsocket) {
ms.CloseChan <- struct{}{}
}
func send(ms *ManagedWebsocket, msg *serverMessage) {
data, err := json.Marshal(msg)
if err != nil {
logErrorf("marshaling message: %w", err)
closeWs(ms)
return
}
ms.OutgoingChan <- data
}
func fatal(ms *ManagedWebsocket, err error) {
send(ms, &serverMessage{
Event: "fatal",
Text: err.Error(),
})
}
func fatalf(ms *ManagedWebsocket, format string, arg ...interface{}) {
fatal(ms, fmt.Errorf(format, arg...))
}
func warn(ms *ManagedWebsocket, err error) {
send(ms, &serverMessage{
Event: "warn",
Text: err.Error(),
})
}
func warnf(ms *ManagedWebsocket, format string, arg ...interface{}) {
warn(ms, fmt.Errorf(format, arg...))
}
func getCommandPrefix() []string {
prefix := os.Getenv("RIJU_AGENT_COMMAND_PREFIX")
if prefix == "" {
logErrorf("must specify RIJU_AGENT_COMMAND_PREFIX for security reasons")
os.Exit(1)
}
if prefix == "0" {
return []string{}
}
list, err := shlex.Split(prefix)
if err != nil {
logErrorf("parsing RIJU_AGENT_COMMAND_PREFIX: %w", err)
os.Exit(1)
}
return list
}
var CommandPrefix = getCommandPrefix()
// https://github.com/gorilla/websocket/blob/76ecc29eff79f0cedf70c530605e486fc32131d1/examples/command/main.go
func handler(w http.ResponseWriter, r *http.Request) {
// Upgrade http connection to websocket
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logErrorf("upgrading connection: %w", err)
return
}
// Set up channels to handle incoming and outgoing websocket
// messages more conveniently, and also to handle closing the
// websocket on error or when we ask.
ms := &ManagedWebsocket{
Socket: ws,
MessageType: websocket.TextMessage,
PingPeriod: 5 * time.Second,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
ms.Init()
// Ensure that websocket will be closed eventually when we
// exit.
defer closeWs(ms)
// Parse request query parameters; do this after upgrading to
// websocket so that we can send errors back on the websocket
// which is easier for clients to parse
cmdline := r.URL.Query()["cmdline"]
if len(cmdline) == 0 {
fatalf(ms, "cmdline query parameter missing")
return
}
cmdline = append(CommandPrefix, cmdline...)
binary, err := exec.LookPath(cmdline[0])
if err != nil {
fatalf(ms, "searching for executable: %w", err)
return
}
// Spawn subprocess
mp, err := NewManagedProcess(binary, cmdline, nil)
if err != nil {
fatalf(ms, "spawning process: %w", err)
return
}
// Ensure eventual process termination
defer func() {
mp.CloseChan <- struct{}{}
}()
// Handle received messages from client
go func() {
for data := range ms.IncomingChan {
msg := clientMessage{}
err := json.Unmarshal(data, &msg)
if err != nil {
warnf(ms, "parsing json: %w", err)
continue
}
switch msg.Event {
case "stdin":
mp.StdinChan <- msg.Data
default:
logWarnf("received unknown event type %s", msg.Event)
}
}
}()
// Proxy stdout and stderr from subprocess
go func() {
for data := range mp.StdoutChan {
msg, err := json.Marshal(&serverMessage{
Event: "stdout",
Data: data,
})
if err != nil {
warnf(ms, "wrapping stdout in json: %w", err)
return
}
ms.OutgoingChan <- msg
}
}()
go func() {
for data := range mp.StderrChan {
msg, err := json.Marshal(&serverMessage{
Event: "stderr",
Data: data,
})
if err != nil {
warnf(ms, "wrapping stderr in json: %w", err)
return
}
ms.OutgoingChan <- msg
}
}()
// Send info about process exit status
exitChan2 := make(chan struct{}, 16)
go func() {
for status := range mp.ExitChan {
exitChan2 <- struct{}{}
code := status.ExitCode()
send(ms, &serverMessage{
Event: "exit",
ExitStatus: &code,
})
}
}()
// Wait until one of subprocess or websocket exits. The other
// one will be cleaned up on return.
select {
case <-exitChan2:
case <-ms.ClosedChan:
}
// Wait a bit to send any pending messages before closing the
// connection.
time.Sleep(1 * time.Second)
return
}
func main() {
port := os.Getenv("RIJU_AGENT_PORT")
if port == "" {
port = "869"
}
host := os.Getenv("RIJU_AGENT_HOST")
if host == "" {
host = "0.0.0.0"
}
fmt.Printf("Listening on http://%s:%s\n", host, port)
mux := http.NewServeMux()
mux.HandleFunc("/exec", handler)
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
err := http.ListenAndServe(fmt.Sprintf("%s:%s", host, port), mux)
if err != nil {
logError(err)
os.Exit(1)
}
}

164
agent/process.go Normal file
View File

@ -0,0 +1,164 @@
package main
import (
"fmt"
"os"
"syscall"
"time"
)
type managedProcess struct {
proc *os.Process
stdinRead *os.File
stdinWrite *os.File
stdoutRead *os.File
stdoutWrite *os.File
stderrRead *os.File
stderrWrite *os.File
internalExitChan chan struct{}
StdinChan chan []byte
StdoutChan chan []byte
StderrChan chan []byte
ExitChan chan *os.ProcessState
CloseChan chan struct{}
}
func NewManagedProcess(name string, argv []string, attr *os.ProcAttr) (*managedProcess, error) {
mp := &managedProcess{
internalExitChan: make(chan struct{}, 16),
StdinChan: make(chan []byte, 16),
StdoutChan: make(chan []byte, 16),
StderrChan: make(chan []byte, 16),
ExitChan: make(chan *os.ProcessState, 16),
CloseChan: make(chan struct{}, 16),
}
done := false
go mp.handleClose()
defer func() {
if !done {
mp.CloseChan <- struct{}{}
}
}()
var err error
mp.stdinRead, mp.stdinWrite, err = os.Pipe()
if err != nil {
return mp, fmt.Errorf("creating stdin pipe: %w", err)
}
mp.stdoutRead, mp.stdoutWrite, err = os.Pipe()
if err != nil {
return mp, fmt.Errorf("creating stdout pipe: %w", err)
}
mp.stderrRead, mp.stderrWrite, err = os.Pipe()
if err != nil {
return mp, fmt.Errorf("creating stderr pipe: %w", err)
}
newAttr := &os.ProcAttr{}
if attr != nil {
*newAttr = *attr
}
if len(newAttr.Files) < 3 {
newAttr.Files = append(newAttr.Files, make([]*os.File, 3-len(newAttr.Files))...)
newAttr.Files[0] = mp.stdinRead
newAttr.Files[1] = mp.stdoutWrite
newAttr.Files[2] = mp.stderrWrite
}
mp.proc, err = os.StartProcess(name, argv, newAttr)
if err != nil {
return mp, fmt.Errorf("spawning process: %w", err)
}
go mp.handleWait()
go mp.handleInput(mp.StdinChan, mp.stdinWrite, "stdin")
go mp.handleOutput(mp.StdoutChan, mp.stdoutRead, "stdout")
go mp.handleOutput(mp.StderrChan, mp.stderrRead, "stderr")
done = true
return mp, nil
}
func (mp *managedProcess) handleInput(ch chan []byte, f *os.File, name string) {
for data := range ch {
_, err := f.Write(data)
if err != nil {
// Likely stdin closed by subprocess, this is normal
return
}
}
}
func (mp *managedProcess) handleOutput(ch chan []byte, f *os.File, name string) {
for {
buf := make([]byte, 1024)
nr, err := f.Read(buf)
if err != nil {
// Likely stdout/stderr closed by subprocess,
// this is normal
return
}
if nr == 0 {
continue
}
ch <- buf[:nr]
}
}
func (mp *managedProcess) handleWait() {
s, err := mp.proc.Wait()
if err != nil {
logErrorf("waiting on process: %w", err)
}
mp.internalExitChan <- struct{}{}
mp.ExitChan <- s
}
func (mp *managedProcess) killProc() {
// See if process has already exited or is about to
select {
case <-mp.internalExitChan:
return
case <-time.NewTimer(500 * time.Millisecond).C:
//
}
// Try killing the process by closing stdin
mp.stdinWrite.Close()
select {
case <-mp.internalExitChan:
return
case <-time.NewTimer(500 * time.Millisecond).C:
//
}
// Try killing the process with SIGTERM, SIGINT, then
// finally SIGKILL
for _, sig := range []os.Signal{syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL} {
err := mp.proc.Signal(sig)
if err != nil {
logErrorf("sending %s to child: %w", sig.String(), err)
}
select {
case <-mp.internalExitChan:
return
case <-time.NewTimer(500 * time.Millisecond).C:
//
}
}
// We are unable to kill the process
logErrorf("unable to kill child process (pid %d)", mp.proc.Pid)
}
func (mp *managedProcess) handleClose() {
<-mp.CloseChan
for _, p := range []*os.File{
mp.stdinRead, mp.stdinWrite,
mp.stdoutRead, mp.stdoutWrite,
mp.stderrRead, mp.stderrWrite,
} {
if p != nil {
p.Close()
}
}
if mp.proc != nil {
//
}
}

107
agent/websocket.go Normal file
View File

@ -0,0 +1,107 @@
package main
import (
"time"
"github.com/gorilla/websocket"
)
type ManagedWebsocket struct {
Socket *websocket.Conn
MessageType int
PingPeriod time.Duration
ReadTimeout time.Duration
WriteTimeout time.Duration
IncomingChan chan []byte
OutgoingChan chan []byte
CloseChan chan struct{}
ClosedChan chan struct{}
}
func (m *ManagedWebsocket) handleIncoming() {
pongChan := make(chan struct{}, 16)
m.Socket.SetPongHandler(func(string) error {
pongChan <- struct{}{}
return nil
})
msgChan := make(chan []byte, 16)
go func() {
defer close(msgChan)
for {
msgtype, data, err := m.Socket.ReadMessage()
if err != nil {
m.Socket.Close()
return
}
if msgtype != m.MessageType {
logWarnf("ignoring message of unexpected type %d", msgtype)
continue
}
msgChan <- data
}
}()
for {
m.Socket.SetReadDeadline(time.Now().Add(m.ReadTimeout))
var msgtype int
var msgdata []byte
select {
case <-pongChan:
msgtype = websocket.PongMessage
case data := <-msgChan:
msgtype = m.MessageType
msgdata = data
}
if msgtype != m.MessageType {
continue
}
m.IncomingChan <- msgdata
}
}
func (m *ManagedWebsocket) handleOutgoing() {
pingTicker := time.NewTicker(m.PingPeriod)
defer pingTicker.Stop()
defer func() {
m.ClosedChan <- struct{}{}
}()
for {
var msgtype int
var msgdata []byte
select {
case <-pingTicker.C:
msgtype = websocket.PingMessage
msgdata = []byte{}
case data := <-m.OutgoingChan:
msgtype = m.MessageType
msgdata = data
case <-m.CloseChan:
msgtype = websocket.CloseMessage
msgdata = websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")
}
wd := time.Now().Add(m.WriteTimeout)
m.Socket.SetWriteDeadline(wd)
err := m.Socket.WriteMessage(msgtype, msgdata)
if err != nil {
m.Socket.Close()
return
}
if msgtype == websocket.CloseMessage {
time.Sleep(wd.Sub(time.Now()))
m.Socket.Close()
return
}
}
}
func (m *ManagedWebsocket) Init() {
m.IncomingChan = make(chan []byte, 16)
m.OutgoingChan = make(chan []byte, 16)
m.CloseChan = make(chan struct{}, 16)
m.ClosedChan = make(chan struct{}, 16)
go m.handleIncoming()
go m.handleOutgoing()
}

209
backend/k8s.js Normal file
View File

@ -0,0 +1,209 @@
import * as k8sClient from "@kubernetes/client-node";
import lodash from "lodash";
const kubeconfig = new k8sClient.KubeConfig();
kubeconfig.loadFromDefault();
const k8s = kubeconfig.makeApiClient(k8sClient.CoreV1Api);
export function watchPods() {
const callbacks = {};
const pods = {};
// https://github.com/kubernetes-client/javascript/blob/1f76ee10c54e33a998abb4686488ccff4285366a/examples/typescript/informer/informer.ts
//
// The watch functionality seems to be wholly undocumented. Copy,
// paste, and pray.
const informer = k8sClient.makeInformer(
kubeconfig,
"/api/v1/namespaces/riju-user/pods",
() => k8s.listNamespacedPod("riju-user")
);
for (const event of ["add", "update", "delete"]) {
informer.on(event, (pod) => {
if (pod.metadata.name in callbacks) {
callbacks[pod.metadata.name](event, pod);
}
pods[pod.metadata.name] = pod;
if (event == "delete") {
delete callbacks[pod.metadata.name];
delete pods[pod.metadata.name];
}
});
}
informer.on("error", (err) => {
console.error(err);
setTimeout(() => informer.start(), 5000);
});
informer.start();
return {
setCallback: (podName, callback) => {
callbacks[podName] = callback;
if (podName in pods) {
callback("add", pods[podName]);
}
},
};
}
export async function listUserSessions() {
return (await k8s.listNamespacedPod("riju-user")).body.items.map((pod) => ({
podName: pod.metadata.name,
sessionID: pod.metadata.labels["riju.codes/user-session-id"],
}));
}
export async function createUserSession({
watcher,
sessionID,
langConfig,
revisions,
}) {
const pod = (
await k8s.createNamespacedPod("riju-user", {
metadata: {
name: `riju-user-session-${sessionID}`,
labels: {
"riju.codes/user-session-id": sessionID,
},
},
spec: {
volumes: [
{
name: "minio-config",
secret: {
secretName: "minio-user-login",
},
},
{
name: "riju-bin",
emptyDir: {},
},
],
imagePullSecrets: [
{
name: "registry-user-login",
},
],
initContainers: [
{
name: "download",
image: "minio/mc:RELEASE.2022-12-13T00-23-28Z",
resources: {},
command: ["sh", "-c"],
args: [
`mkdir -p /root/.mc && cp -LT /mc/config.json /root/.mc/config.json &&` +
`mc cp riju/agent/${revisions.agent} /riju-bin/agent && chmod +x /riju-bin/agent &&` +
`mc cp riju/ptyify/${revisions.ptyify} /riju-bin/ptyify && chmod +x /riju-bin/ptyify`,
],
volumeMounts: [
{
name: "minio-config",
mountPath: "/mc",
readOnly: true,
},
{
name: "riju-bin",
mountPath: "/riju-bin",
},
],
},
],
containers: [
{
name: "session",
image: `localhost:30999/riju-lang:${langConfig.id}-${revisions.langImage}`,
resources: {
requests: {},
limits: {
cpu: "1000m",
memory: "4Gi",
},
},
command: ["/riju-bin/agent"],
env: [
{
name: "RIJU_AGENT_COMMAND_PREFIX",
value: "runuser -u riju --",
},
],
securityContext: {
runAsUser: 0,
},
startupProbe: {
httpGet: {
path: "/health",
port: 869,
scheme: "HTTP",
},
failureThreshold: 30,
initialDelaySeconds: 0,
periodSeconds: 1,
successThreshold: 1,
timeoutSeconds: 2,
},
readinessProbe: {
httpGet: {
path: "/health",
port: 869,
scheme: "HTTP",
},
failureThreshold: 1,
initialDelaySeconds: 2,
periodSeconds: 10,
successThreshold: 1,
timeoutSeconds: 2,
},
livenessProbe: {
httpGet: {
path: "/health",
port: 869,
scheme: "HTTP",
},
failureThreshold: 3,
initialDelaySeconds: 2,
periodSeconds: 10,
successThreshold: 1,
timeoutSeconds: 2,
},
volumeMounts: [
{
name: "riju-bin",
mountPath: "/riju-bin",
readOnly: true,
},
],
},
],
restartPolicy: "Never",
},
})
).body;
const podIP = await new Promise((resolve, reject) => {
setTimeout(() => reject("timed out"), 5 * 60 * 1000);
watcher.setCallback(pod.metadata.name, (event, pod) => {
if (event == "delete") {
reject(new Error("pod was deleted"));
} else if (pod.status.phase === "Failed") {
reject(new Error("pod status became Failed"));
} else if (
pod.status.podIP &&
lodash.every(pod.status.containerStatuses, (status) => status.ready)
) {
resolve(pod.status.podIP);
} else {
console.log(event, JSON.stringify(pod.status, null, 2));
}
});
});
return podIP;
}
export async function deleteUserSessions(sessionsToDelete) {
for (const { podName } of sessionsToDelete) {
await k8s.deleteNamespacedPod(podName, "riju-user");
}
}

View File

@ -1,5 +1,4 @@
import fsOrig, { promises as fs } from "fs";
import path from "path";
import fsOrig from "fs";
import debounce from "debounce";

80
backend/sandbox-k8s.js Normal file
View File

@ -0,0 +1,80 @@
import { spawn } from "child_process";
import { promises as fs } from "fs";
import process from "process";
import { readLangConfig } from "../lib/yaml.js";
import * as k8s from "./k8s.js";
import { getUUID, quote } from "./util.js";
function die(msg) {
console.error(msg);
process.exit(1);
}
async function main() {
const sandboxScript = await fs.readFile("backend/sandbox.bash", "utf-8");
const lang = process.env.L;
if (!lang) {
die("environment variable unset: $L");
}
const langConfig = await readLangConfig(lang);
console.log(`Checking for existing sessions`);
const existingSessions = await k8s.listUserSessions();
if (existingSessions.length > 0) {
console.log(`Killing ${existingSessions.length} existing session(s)`);
await k8s.deleteUserSessions(existingSessions);
}
const sessionID = getUUID();
console.log(`Starting session with UUID ${sessionID}`);
const watcher = k8s.watchPods();
await k8s.createUserSession({
watcher,
sessionID,
langConfig,
revisions: {
agent: "20221229-002450-semantic-moccasin-albatross",
ptyify: "20221228-023645-clean-white-gorilla",
langImage: "20221227-195753-forward-harlequin-wolverine",
},
});
// let buffer = "";
// await new Promise((resolve) => {
// session.stdout.on("data", (data) => {
// buffer += data.toString();
// let idx;
// while ((idx = buffer.indexOf("\n")) !== -1) {
// const line = buffer.slice(0, idx);
// buffer = buffer.slice(idx + 1);
// if (line === "riju: container ready") {
// resolve();
// } else {
// console.error(line);
// }
// }
// });
// });
// const args = [].concat.apply(
// ["riju-pty", "-f"],
// privilegedPty(
// { uuid },
// bash(
// `env L='${lang}' LANG_CONFIG=${quote(
// JSON.stringify(langConfig)
// )} bash --rcfile <(cat <<< ${quote(sandboxScript)})`
// )
// )
// );
// const proc = spawn(args[0], args.slice(1), {
// stdio: "inherit",
// });
// try {
// await new Promise((resolve, reject) => {
// proc.on("error", reject);
// proc.on("close", resolve);
// });
// } finally {
// session.kill();
// }
}
main().catch(die);

View File

@ -1,17 +1,18 @@
#!/usr/bin/env bash
# This script is sourced by Bash within 'make sandbox'.
if [[ -z "$L" ]]; then
echo 'environment variable unset: $L' >&2
echo "environment variable unset: \$L" >&2
exit 1
fi
if [[ -z "$LANG_CONFIG" ]]; then
echo 'environment variable unset: $LANG_CONFIG' >&2
echo "environment variable unset: \$LANG_CONFIG" >&2
exit 1
fi
function get {
jq -r ".$1" <<< "${LANG_CONFIG}"
jq -r ".$1" <<<"${LANG_CONFIG}"
}
function has {
@ -24,21 +25,21 @@ function riju-exec {
function daemon {
if has daemon; then
echo "$(get daemon)"
get daemon
riju-exec "$(get daemon)"
fi
}
function setup {
if has setup; then
echo "$(get setup)"
get setup
riju-exec "$(get setup)"
fi
}
function repl {
if has repl; then
echo "$(get repl)"
get repl
riju-exec "$(get repl)"
fi
}
@ -47,22 +48,22 @@ function main {
if get main | grep -q /; then
mkdir -p "$(dirname "$(get main)")"
fi
: > "$(get main)"
has prefix && get prefix >> "$(get main)"
get template >> "$(get main)"
has suffix && get suffix >> "$(get main)"
: >"$(get main)"
has prefix && get prefix >>"$(get main)"
get template >>"$(get main)"
has suffix && get suffix >>"$(get main)"
}
function compile {
if has compile; then
echo "$(get compile)"
get compile
riju-exec "$(get compile)"
fi
}
function run-only {
if has run; then
echo "$(get run)"
get run
riju-exec "$(get run)"
fi
}
@ -73,18 +74,18 @@ function run {
function format {
if has format; then
echo "$(get format.run)"
get format.run
riju-exec "( $(get format.run) ) < $(get main)"
fi
}
function lsp {
if has lsp.setup; then
echo "$(get lsp.setup)"
get lsp.setup
riju-exec "$(get lsp.setup)"
fi
if has lsp; then
echo "$(get lsp.start)"
get lsp.start
riju-exec "$(get lsp.start)"
fi
}

View File

@ -6,11 +6,9 @@ import { readLangConfig } from "../lib/yaml.js";
import {
bash,
getUUID,
privilegedExec,
privilegedPty,
privilegedSession,
quote,
run,
} from "./util.js";
function die(msg) {
@ -18,10 +16,6 @@ function die(msg) {
process.exit(1);
}
function log(msg) {
console.log(msg);
}
async function main() {
const sandboxScript = await fs.readFile("backend/sandbox.bash", "utf-8");
const lang = process.env.L;

View File

@ -10,7 +10,7 @@ import { getTestHash } from "../lib/hash-test.js";
import * as api from "./api.js";
import { langsPromise } from "./langs.js";
import { shutdown } from "./shutdown.js";
import { getUUID, run } from "./util.js";
import { run } from "./util.js";
let langs = {};
@ -525,7 +525,7 @@ const testTypes = {
ensure: {
pred: ({ ensure }) => (ensure ? true : false),
},
run: { pred: (config) => true },
run: { pred: (_config) => true },
repl: {
pred: ({ repl }) => (repl ? true : false),
},

View File

@ -1,5 +1,4 @@
import { spawn } from "child_process";
import os from "os";
import process from "process";
import * as Sentry from "@sentry/node";
@ -86,6 +85,14 @@ export async function run(args, log, options) {
});
}
export function privilegedList() {
return [rijuSystemPrivileged, "list"];
}
export function privilegedPull({ repo, tag }) {
return [rijuSystemPrivileged, "pull", repo, tag];
}
export function privilegedSession({ uuid, lang }) {
const cmdline = [rijuSystemPrivileged, "session", uuid, lang];
if (imageHashes[lang]) {

33
env.yaml.bash Executable file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
registry_password="$(pwgen -s 20 1)"
proxy_password="$(pwgen -s 20 1)"
cat <<EOF
networking:
domain: riju.example.com # FIXME
ip: x.y.z.w # FIXME
contact:
letsEncryptEmail: ops@example.com # FIXME
letsEncryptProductionEnabled: false
metallb:
secretkey: "$(pwgen -s 256 1)"
registry:
password: "${registry_password}"
htpasswd: "$(htpasswd -nbB admin "${registry_password}")"
minio:
accessKey: "$(head -c16 /dev/urandom | xxd -p)"
secretKey: "$(head -c16 /dev/urandom | xxd -p)"
proxy:
password: "${proxy_password}"
htpasswd: "$(htpasswd -nbB admin "${proxy_password}")"
EOF

105
k8s/cluster.yaml Normal file
View File

@ -0,0 +1,105 @@
apiVersion: k0s.k0sproject.io/v1beta1
kind: ClusterConfig
metadata:
creationTimestamp: null
name: k0s
spec:
api:
address: 192.168.0.216
k0sApiPort: 9443
port: 6443
sans:
- 192.168.0.216
- 192.168.122.1
- 172.21.0.1
- 172.17.0.1
- 172.23.0.1
- 10.88.0.1
- 10.244.0.1
- 2601:646:4000:3060::be49
- 2601:646:4000:3060:8b13:5b76:2703:28f
- 2601:646:4000:3060:683c:7a51:eee8:2eb
- fe80::1fbd:2949:a12e:cedf
- fe80::42:d5ff:fe58:a84f
- fe80::844c:59ff:fe46:20dc
- fe80::20e5:9dff:fe7a:4698
- fe80::f86c:22ff:feb0:59ac
- fe80::b0d0:51ff:fe45:ce31
- fe80::3cd5:9eff:fed1:5f72
tunneledNetworkingMode: false
controllerManager: {}
extensions:
helm:
charts: null
repositories: null
storage:
type: openebs_local_storage
images:
calico:
cni:
image: docker.io/calico/cni
version: v3.24.5
kubecontrollers:
image: docker.io/calico/kube-controllers
version: v3.24.5
node:
image: docker.io/calico/node
version: v3.24.5
coredns:
image: docker.io/coredns/coredns
version: 1.9.4
default_pull_policy: IfNotPresent
konnectivity:
image: quay.io/k0sproject/apiserver-network-proxy-agent
version: 0.0.32-k0s1
kubeproxy:
image: registry.k8s.io/kube-proxy
version: v1.25.4
kuberouter:
cni:
image: docker.io/cloudnativelabs/kube-router
version: v1.5.1
cniInstaller:
image: quay.io/k0sproject/cni-node
version: 1.1.1-k0s.0
metricsserver:
image: registry.k8s.io/metrics-server/metrics-server
version: v0.6.1
pushgateway:
image: quay.io/k0sproject/pushgateway-ttl
version: edge@sha256:7031f6bf6c957e2fdb496161fe3bea0a5bde3de800deeba7b2155187196ecbd9
installConfig:
users:
etcdUser: etcd
kineUser: kube-apiserver
konnectivityUser: konnectivity-server
kubeAPIserverUser: kube-apiserver
kubeSchedulerUser: kube-scheduler
konnectivity:
adminPort: 8133
agentPort: 8132
network:
calico: null
clusterDomain: cluster.local
dualStack: {}
kubeProxy:
mode: iptables
kuberouter:
autoMTU: true
hairpinMode: false
metricsPort: 8080
mtu: 0
peerRouterASNs: ""
peerRouterIPs: ""
podCIDR: 10.244.0.0/16
provider: kuberouter
serviceCIDR: 10.96.0.0/12
scheduler: {}
storage:
etcd:
externalCluster: null
peerAddress: 192.168.0.216
type: etcd
telemetry:
enabled: true
status: {}

View File

@ -0,0 +1,9 @@
---
kind: IPAddressPool
apiVersion: metallb.io/v1beta1
metadata:
namespace: metallb
name: self
spec:
addresses:
- "{{ .networking.ip }}/32"

1108
k8s/metallb-crds.yaml Normal file

File diff suppressed because it is too large Load Diff

352
k8s/metallb-rbac.yaml Normal file
View File

@ -0,0 +1,352 @@
# Based on bitnami/metallb helm chart 4.1.12 for metallb 0.13.7
---
kind: ServiceAccount
apiVersion: v1
metadata:
namespace: metallb
name: metallb-controller
automountServiceAccountToken: true
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: metallb-controller
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- update
- apiGroups:
- ""
resources:
- services/status
verbs:
- update
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- policy
resourceNames:
- metallb-controller
resources:
- podsecuritypolicies
verbs:
- use
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
- mutatingwebhookconfigurations
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metallb-controller
subjects:
- kind: ServiceAccount
namespace: metallb
name: metallb-controller
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: metallb-controller
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: metallb
name: metallb-controller
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
resourceNames:
- metallb-memberlist
verbs:
- list
- apiGroups:
- apps
resources:
- deployments
resourceNames:
- metallb-controller
verbs:
- get
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metallb.io
resources:
- addresspools
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- ipaddresspools
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bgppeers
verbs:
- get
- list
- apiGroups:
- metallb.io
resources:
- bgpadvertisements
verbs:
- get
- list
- apiGroups:
- metallb.io
resources:
- l2advertisements
verbs:
- get
- list
- apiGroups:
- metallb.io
resources:
- communities
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bfdprofiles
verbs:
- get
- list
- watch
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: metallb
name: metallb-controller
subjects:
- kind: ServiceAccount
namespace: metallb
name: metallb-controller
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: metallb-controller
---
kind: ServiceAccount
apiVersion: v1
metadata:
namespace: metallb
name: metallb-speaker
automountServiceAccountToken: true
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: metallb-speaker
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- policy
resourceNames:
- metallb-speaker
resources:
- podsecuritypolicies
verbs:
- use
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metallb-speaker
subjects:
- kind: ServiceAccount
namespace: metallb
name: metallb-speaker
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: metallb-speaker
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: metallb
name: metallb-pod-lister
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- addresspools
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bfdprofiles
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bgppeers
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- l2advertisements
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bgpadvertisements
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- ipaddresspools
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- communities
verbs:
- get
- list
- watch
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: metallb
name: metallb-pod-lister
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: metallb-pod-lister
subjects:
- kind: ServiceAccount
name: metallb-speaker

326
k8s/metallb.yaml Normal file
View File

@ -0,0 +1,326 @@
# Based on bitnami/metallb helm chart 4.1.12 for metallb 0.13.7
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
namespace: metallb
name: metallb-speaker
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: metallb-speaker
template:
metadata:
labels:
app: metallb-speaker
spec:
serviceAccountName: metallb-speaker
hostNetwork: true
securityContext:
fsGroup: 0
terminationGracePeriodSeconds: 2
containers:
- name: metallb-speaker
image: "docker.io/bitnami/metallb-speaker:0.13.7-debian-11-r8"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_ADMIN
drop:
- ALL
readOnlyRootFilesystem: true
runAsUser: 0
args:
- "--port=7472"
env:
- name: METALLB_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: METALLB_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: METALLB_ML_BIND_ADDR
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: METALLB_ML_LABELS
value: app=metallb-speaker
- name: METALLB_ML_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: METALLB_ML_SECRET_KEY
valueFrom:
secretKeyRef:
name: metallb-memberlist
key: secretkey
ports:
- name: metrics
containerPort: 7472
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
httpGet:
path: /metrics
port: metrics
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
httpGet:
path: /metrics
port: metrics
resources: {}
---
kind: Secret
apiVersion: v1
metadata:
namespace: metallb
name: webhook-server-cert
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: metallb
name: metallb-controller
labels:
app.kubernetes.io/name: metallb
spec:
replicas: 1
strategy:
type: RollingUpdate
revisionHistoryLimit: 3
selector:
matchLabels:
app: metallb-controller
template:
metadata:
labels:
app: metallb-controller
spec:
serviceAccountName: metallb-controller
securityContext:
fsGroup: 1001
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
containers:
- name: metallb-controller
image: "docker.io/bitnami/metallb-controller:0.13.7-debian-11-r9"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
args:
- --port=7472
- --cert-service-name=metallb-webhook-service
ports:
- name: webhook-server
containerPort: 9443
- name: metrics
containerPort: 7472
volumeMounts:
- name: cert
mountPath: /tmp/k8s-webhook-server/serving-certs
readOnly: true
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
httpGet:
path: /metrics
port: metrics
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
httpGet:
path: /metrics
port: metrics
resources: {}
---
kind: Service
apiVersion: v1
metadata:
namespace: metallb
name: metallb-webhook-service
spec:
ports:
- port: 443
targetPort: 9443
selector:
app: metallb-controller
---
kind: ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
metadata:
name: metallb-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-addresspool
failurePolicy: Fail
name: addresspoolvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- addresspools
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta2-bgppeer
failurePolicy: Fail
name: bgppeervalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta2
operations:
- CREATE
- UPDATE
resources:
- bgppeers
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-ipaddresspool
failurePolicy: Fail
name: ipaddresspoolvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- ipaddresspools
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-bgpadvertisement
failurePolicy: Fail
name: bgpadvertisementvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- bgpadvertisements
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-community
failurePolicy: Fail
name: communityvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- communities
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-bfdprofile
failurePolicy: Fail
name: bfdprofileyvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- DELETE
resources:
- bfdprofiles
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-l2advertisement
failurePolicy: Fail
name: l2advertisementvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- l2advertisements
sideEffects: None

23
k8s/namespaces.yaml Normal file
View File

@ -0,0 +1,23 @@
---
kind: Namespace
apiVersion: v1
metadata:
name: traefik
---
kind: Namespace
apiVersion: v1
metadata:
name: metallb
---
kind: Namespace
apiVersion: v1
metadata:
name: riju
---
kind: Namespace
apiVersion: v1
metadata:
name: riju-user

25
k8s/provisioning.md Normal file
View File

@ -0,0 +1,25 @@
```bash
curl -sSLf https://get.k0s.sh | sudo sh
sudo mkdir /etc/k0s
k0s config create > /etc/k0s/k0s.yaml
```
Edit to have this config:
```yaml
spec:
extensions:
storage:
type: openebs_local_storage
```
```bash
sudo k0s install controller --single
sudo k0s start
```
Go to client machine:
```bash
ssh riju-k8s sudo -S k0s kubeconfig admin > ~/.kube/config
```

View File

@ -0,0 +1,102 @@
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
namespace: riju
name: docker-registry
spec:
replicas: 1
serviceName: docker-registry
selector:
matchLabels:
app: docker-registry
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 128Gi
storageClassName: openebs-hostpath
template:
metadata:
labels:
app: docker-registry
spec:
volumes:
- name: auth
secret:
secretName: registry-auth
containers:
- name: registry
image: "registry:2"
resources: {}
readinessProbe:
httpGet:
path: /
port: 5000
scheme: HTTP
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /
port: 5000
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
env:
- name: REGISTRY_AUTH
value: htpasswd
- name: REGISTRY_AUTH_HTPASSWD_REALM
value: "Registry Realm"
- name: REGISTRY_AUTH_HTPASSWD_PATH
value: /var/run/registry/auth/htpasswd
ports:
- name: api
containerPort: 5000
volumeMounts:
- name: auth
mountPath: /var/run/registry/auth
- name: data
mountPath: /var/lib/registry
---
kind: Service
apiVersion: v1
metadata:
namespace: riju
name: docker-registry
spec:
selector:
app: docker-registry
type: NodePort
ports:
- name: api
port: 80
nodePort: 30999
targetPort: 5000
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
namespace: riju
name: docker-registry
spec:
entryPoints:
- docker
routes:
- kind: Rule
match: "PathPrefix(`/`)"
services:
- namespace: riju
name: docker-registry
port: 80

101
k8s/riju-minio.yaml Normal file
View File

@ -0,0 +1,101 @@
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
namespace: riju
name: minio
spec:
replicas: 1
serviceName: minio
selector:
matchLabels:
app: minio
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 16Gi
storageClassName: openebs-hostpath
template:
metadata:
labels:
app: minio
spec:
containers:
- name: minio
image: "minio/minio:RELEASE.2022-12-12T19-27-27Z"
resources: {}
readinessProbe:
httpGet:
path: /minio/health/live
port: 9000
scheme: HTTP
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /minio/health/live
port: 9000
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
args:
- "server"
- "/data"
env:
- name: MINIO_ACCESS_KEY
valueFrom:
secretKeyRef:
name: minio-keys
key: access-key
- name: MINIO_SECRET_KEY
valueFrom:
secretKeyRef:
name: minio-keys
key: secret-key
ports:
- name: api
containerPort: 9000
volumeMounts:
- name: data
mountPath: /data
---
kind: Service
apiVersion: v1
metadata:
namespace: riju
name: minio
spec:
selector:
app: minio
ports:
- name: api
port: 80
targetPort: 9000
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
namespace: riju
name: minio
spec:
entryPoints:
- minio
routes:
- kind: Rule
match: "PathPrefix(`/`)"
services:
- namespace: riju
name: minio
port: 80

117
k8s/riju-proxy.yaml Normal file
View File

@ -0,0 +1,117 @@
---
kind: ConfigMap
apiVersion: v1
metadata:
namespace: riju
name: riju-proxy-config
data:
default.conf: |
underscores_in_headers on;
server {
resolver kube-dns.kube-system.svc.cluster.local;
listen 1869 default_server;
auth_basic "Riju administrative proxy";
auth_basic_user_file /etc/nginx/passwd;
location ~ /(10\.[0-9]+\.[0-9]+\.[0-9]+)/health {
proxy_pass http://$1:869/health;
}
location ~ /(10\.[0-9]+\.[0-9]+\.[0-9]+)/exec {
proxy_pass http://$1:869/exec$is_args$args;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location / {
return 404;
}
}
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: riju
name: riju-proxy
spec:
replicas: 1
selector:
matchLabels:
app: riju-proxy
template:
metadata:
labels:
app: riju-proxy
spec:
volumes:
- name: config
configMap:
name: riju-proxy-config
- name: auth
secret:
secretName: riju-proxy-auth
containers:
- name: nginx
image: "nginx:1.23"
resources: {}
readinessProbe:
tcpSocket:
port: 1869
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
tcpSocket:
port: 1869
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
ports:
- name: http
containerPort: 1869
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
- name: auth
mountPath: /etc/nginx/passwd
subPath: htpasswd
---
kind: Service
apiVersion: v1
metadata:
namespace: riju
name: riju-proxy
spec:
selector:
app: riju-proxy
ports:
- name: http
port: 1869
targetPort: 1869
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
namespace: riju
name: riju-proxy
spec:
entryPoints:
- proxy
routes:
- kind: Rule
match: "PathPrefix(`/`)"
services:
- namespace: riju
name: riju-proxy
port: 1869

89
k8s/riju-server.yaml Normal file
View File

@ -0,0 +1,89 @@
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: riju
name: riju-server
spec:
replicas: 1
selector:
matchLabels:
app: riju-server
template:
metadata:
labels:
app: riju-server
spec:
volumes:
- name: cache
hostPath:
path: /var/cache/riju
- name: docker
hostPath:
path: /var/run/docker.sock
imagePullSecrets:
- name: registry-login
containers:
- name: server
image: "localhost:30999/riju:app"
resources: {}
readinessProbe:
httpGet:
path: /
port: 6119
scheme: HTTP
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /
port: 6119
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
ports:
- name: http
containerPort: 6119
volumeMounts:
- name: cache
mountPath: /var/cache/riju
- name: docker
mountPath: /var/run/docker.sock
readOnly: true
---
kind: Service
apiVersion: v1
metadata:
namespace: riju
name: riju-server
spec:
selector:
app: riju-server
ports:
- name: http
port: 80
targetPort: 6119
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
namespace: riju
name: riju-server
spec:
entryPoints:
- https
routes:
- kind: Rule
match: "PathPrefix(`/`)"
services:
- namespace: riju
name: riju-server
port: 80

95
k8s/secrets.in.yaml Normal file
View File

@ -0,0 +1,95 @@
---
kind: Secret
apiVersion: v1
metadata:
namespace: metallb
name: metallb-memberlist
data:
secretkey: "{{ .metallb.secretkey | b64enc }}"
---
kind: Secret
apiVersion: v1
metadata:
namespace: riju
name: registry-auth
data:
htpasswd: "{{ .registry.htpasswd | println | b64enc }}"
---
kind: Secret
apiVersion: v1
metadata:
namespace: riju
name: registry-login
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"localhost:30999": {
"username": "admin",
"password": "{{ .registry.password }}",
"auth": "{{ .registry.password | printf "admin:%s" | b64enc }}"
}
}
}
---
kind: Secret
apiVersion: v1
metadata:
namespace: riju-user
name: registry-user-login
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"localhost:30999": {
"username": "admin",
"password": "{{ .registry.password }}",
"auth": "{{ .registry.password | printf "admin:%s" | b64enc }}"
}
}
}
---
kind: Secret
apiVersion: v1
metadata:
namespace: riju
name: minio-keys
stringData:
access-key: "{{ .minio.accessKey }}"
secret-key: "{{ .minio.secretKey }}"
---
kind: Secret
apiVersion: v1
metadata:
namespace: riju-user
name: minio-user-login
stringData:
config.json: |
{
"version": "10",
"aliases": {
"riju": {
"url": "http://minio.riju.svc",
"accessKey": "{{ .minio.accessKey }}",
"secretKey": "{{ .minio.secretKey }}",
"api": "s3v4",
"path": "auto"
}
}
}
---
kind: Secret
apiVersion: v1
metadata:
namespace: riju
name: riju-proxy-auth
data:
htpasswd: "{{ .proxy.htpasswd | println | b64enc }}"

View File

@ -0,0 +1,60 @@
---
kind: ConfigMap
apiVersion: v1
metadata:
namespace: traefik
name: traefik-config
data:
traefik.yaml: |
entryPoints:
proxy:
address: ":1869"
http:
tls:
certResolver: riju
domains:
- main: k8s.riju.codes
http:
address: ":8000"
https:
address: ":8443"
http:
tls:
certResolver: riju
domains:
- main: k8s.riju.codes
healthcheck:
address: ":9000"
metrics:
address: ":9100"
docker:
address: ":31000"
http:
tls:
certResolver: riju
domains:
- main: k8s.riju.codes
minio:
address: ":32000"
http:
tls:
certResolver: riju
domains:
- main: k8s.riju.codes
ping:
entryPoint: "healthcheck"
metrics:
prometheus:
entryPoint: "metrics"
providers:
kubernetesCRD: {}
certificatesResolvers:
riju:
acme:
{{- if not .contact.letsEncryptProductionEnabled }}
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
{{- end }}
email: "{{ .contact.letsEncryptEmail }}"
storage: /data/acme.json
httpChallenge:
entryPoint: http

2288
k8s/traefik-crds.yaml Normal file

File diff suppressed because it is too large Load Diff

72
k8s/traefik-rbac.yaml Normal file
View File

@ -0,0 +1,72 @@
# Based on traefik/traefik helm chart 20.8.0 for traefik v2.9.6
---
kind: ServiceAccount
apiVersion: v1
metadata:
namespace: traefik
name: traefik
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik
rules:
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingressclasses
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- tlsoptions
- tlsstores
- traefikservices
- serverstransports
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: traefik
subjects:
- namespace: traefik
kind: ServiceAccount
name: traefik

150
k8s/traefik.yaml Normal file
View File

@ -0,0 +1,150 @@
# Based on traefik/traefik helm chart 20.8.0 for traefik v2.9.6
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
namespace: traefik
name: traefik-data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 128Mi
storageClassName: openebs-hostpath
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: traefik
name: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
minReadySeconds: 0
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "9100"
labels:
app: traefik
spec:
serviceAccountName: traefik
terminationGracePeriodSeconds: 60
hostNetwork: false
initContainers:
- name: volume-permissions
image: busybox:1.35
command:
- "sh"
- "-c"
- "touch /data/acme.json && chmod -Rv 600 /data/* && chown 65532:65532 /data/acme.json"
volumeMounts:
- name: data
mountPath: /data
containers:
- image: traefik:v2.9.6
imagePullPolicy: IfNotPresent
name: traefik
resources: {}
readinessProbe:
httpGet:
path: /ping
port: 9000
scheme: HTTP
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /ping
port: 9000
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
ports:
- name: http
containerPort: 8000
- name: https
containerPort: 8443
- name: ping
containerPort: 9000
- name: docker
containerPort: 31000
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532
volumeMounts:
- name: config
mountPath: /etc/traefik
- name: data
mountPath: /data
- name: tmp
mountPath: /tmp
volumes:
- name: config
configMap:
name: traefik-config
- name: data
persistentVolumeClaim:
claimName: traefik-data
- name: tmp
emptyDir: {}
securityContext:
fsGroup: 65532
---
kind: Service
apiVersion: v1
metadata:
namespace: traefik
name: traefik
annotations:
metallb.universe.tf/allow-shared-ip: main
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- port: 80
name: http
targetPort: 8000
- port: 443
name: https
targetPort: 8443
- port: 1869
name: proxy
- port: 31000
name: docker
- port: 32000
name: minio
---
kind: IngressClass
apiVersion: networking.k8s.io/v1
metadata:
name: traefik
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: traefik.io/ingress-controller

View File

@ -9,6 +9,7 @@
"@babel/parser": "^7.13.11",
"@babel/preset-env": "^7.12.11",
"@balena/dockerignore": "^1.0.2",
"@kubernetes/client-node": "^0.18.0",
"@sentry/node": "^6.11.0",
"async-lock": "^1.2.6",
"babel-loader": "^8.2.2",
@ -36,6 +37,7 @@
"semaphore": "^1.1.0",
"strip-ansi": "^6.0.0",
"style-loader": "^2.0.0",
"unique-names-generator": "^4.7.1",
"uuid": "^8.3.2",
"vscode-languageserver-protocol": "3.15.3",
"webpack": "^4.44.2",

View File

@ -30,6 +30,8 @@ void init() { sentinel_bash[sentinel_bash_len - 1] = '\0'; }
void die_with_usage()
{
die("usage:\n"
" riju-system-privileged list\n"
" riju-system-privileged pull REPO TAG\n"
" riju-system-privileged session UUID LANG [IMAGE-HASH]\n"
" riju-system-privileged exec UUID CMDLINE...\n"
" riju-system-privileged pty UUID CMDLINE...\n"
@ -117,6 +119,28 @@ char *parseImageHash(char *imageHash)
return imageHash;
}
char *parseRepo(char *repo)
{
if (strnlen(repo, 501) > 500)
die("illegal repo name");
for (char *ptr = repo; *ptr; ++ptr)
if (!((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= '0' && *ptr <= '9') ||
*ptr == '/' || *ptr == '.' || *ptr == '-' || *ptr == '_'))
die("illegal repo name");
return repo;
}
char *parseTag(char *tag)
{
if (strnlen(tag, 501) > 500)
die("illegal tag name");
for (char *ptr = tag; *ptr; ++ptr)
if (!((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= '0' && *ptr <= '9') ||
*ptr == '.' || *ptr == '-' || *ptr == '_'))
die("illegal tag name");
return tag;
}
char *timeout_msg;
void sigalrm_die(int signum)
@ -132,7 +156,81 @@ void sigalrm_kill_parent(int signum)
exit(EXIT_FAILURE);
}
void session(char *uuid, char *lang, char *imageHash)
void cmd_list()
{
// This command prints a bunch of empty lines because there is no
// way to filter to a desired set of images. Caller is expected to
// remove empty lines because it's easier in JS than C.
char *argv[] = {
"docker",
"image",
"ls",
"--format",
"{{ if eq .Repository \"riju\" }}{{ .Tag }}{{ end }}",
NULL,
};
execvp(argv[0], argv);
die("execvp failed");
}
void cmd_pull(char *repo, char *tag)
{
char *localImage, *remoteImage;
if (asprintf(&remoteImage, "%s:%s", repo, tag) < 0)
die("asprintf failed");
if (asprintf(&localImage, "riju:%s", tag) < 0)
die("asprintf failed");
pid_t orig_ppid = getpid();
pid_t pid = fork();
if (pid < 0)
die("fork failed");
else if (pid == 0) {
if (freopen("/dev/null", "w", stdout) == NULL)
die("freopen failed");
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
char *argv[] = {
"docker", "inspect", "--", localImage, NULL,
};
execvp(argv[0], argv);
die("execvp failed");
}
siginfo_t info;
if (waitid(P_PID, pid, &info, WEXITED) < 0)
die("waitid failed");
if (info.si_status == 0) {
// Image exists already, no need to pull. It is only appropriate
// to use cmd_pull with immutable images.
return;
}
orig_ppid = getpid();
pid = fork();
if (pid < 0)
die("fork failed");
else if (pid == 0) {
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
char *argv[] = {
"docker", "pull", "--", remoteImage, NULL,
};
execvp(argv[0], argv);
}
if (waitid(P_PID, pid, &info, WEXITED) < 0)
die("waitid failed");
if (info.si_status != 0)
die("child process failed");
char *argv[] = {
"docker", "tag", "--", remoteImage, localImage,
};
execvp(argv[0], argv);
die("execvp failed");
}
void cmd_session(char *uuid, char *lang, char *imageHash)
{
if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
die("setvbuf failed");
@ -295,7 +393,7 @@ void session(char *uuid, char *lang, char *imageHash)
}
}
void exec(char *uuid, int argc, char **cmdline, bool pty)
void cmd_exec(char *uuid, int argc, char **cmdline, bool pty)
{
if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
die("setvbuf failed");
@ -463,7 +561,7 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
}
}
void teardown(char *uuid)
void cmd_teardown(char *uuid)
{
if (setuid(0) != 0)
die("setuid failed");
@ -491,31 +589,45 @@ int main(int argc, char **argv)
die("seteuid failed");
if (argc < 2)
die_with_usage();
if (!strcmp(argv[1], "list")) {
if (argc != 2)
die_with_usage();
cmd_list();
return 0;
}
if (!strcmp(argv[1], "pull")) {
if (argc != 4)
die_with_usage();
char *repo = parseRepo(argv[2]);
char *tag = parseTag(argv[3]);
cmd_pull(repo, tag);
return 0;
}
if (!strcmp(argv[1], "session")) {
if (argc < 4 || argc > 5)
die_with_usage();
char *uuid = parseUUID(argv[2]);
char *lang = parseLang(argv[3]);
char *imageHash = argc == 5 ? parseImageHash(argv[4]) : NULL;
session(uuid, lang, imageHash);
cmd_session(uuid, lang, imageHash);
return 0;
}
if (!strcmp(argv[1], "exec")) {
if (argc < 4)
die_with_usage();
exec(parseUUID(argv[2]), argc - 3, &argv[3], false);
cmd_exec(parseUUID(argv[2]), argc - 3, &argv[3], false);
return 0;
}
if (!strcmp(argv[1], "pty")) {
if (argc < 4)
die_with_usage();
exec(parseUUID(argv[2]), argc - 3, &argv[3], true);
cmd_exec(parseUUID(argv[2]), argc - 3, &argv[3], true);
return 0;
}
if (!strcmp(argv[1], "teardown")) {
if (argc < 2)
die_with_usage();
teardown(argc >= 3 ? parseUUID(argv[2]) : NULL);
cmd_teardown(argc >= 3 ? parseUUID(argv[2]) : NULL);
return 0;
}
die_with_usage();

5
tools/template/Makefile Normal file
View File

@ -0,0 +1,5 @@
bin:
mkdir bin
bin/template: bin go.mod go.sum template.go
go build -o bin/template template.go

8
tools/template/go.mod Normal file
View File

@ -0,0 +1,8 @@
module github.com/raxod502/riju/tools/go
go 1.16
require (
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
gopkg.in/yaml.v2 v2.4.0
)

39
tools/template/go.sum Normal file
View File

@ -0,0 +1,39 @@
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

7
tools/template/template Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
make -s bin/template
exec bin/template

View File

@ -0,0 +1,88 @@
package main
import (
"bytes"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
"gopkg.in/yaml.v2"
)
func findProjectRoot() (string, error) {
curDir, err := os.Getwd()
if err != nil {
return "", err
}
prevDir := ""
for curDir != prevDir {
if _, err := os.Stat(filepath.Join(curDir, ".git")); err == nil {
return curDir, nil
} else if !os.IsNotExist(err) {
return "", err
}
prevDir = curDir
curDir = filepath.Dir(curDir)
}
return "", fmt.Errorf("not a git repository (or any of the parent directories): .git")
}
func mainInternal() error {
projectRoot, err := findProjectRoot()
if err != nil {
return err
}
envText, err := os.ReadFile(filepath.Join(projectRoot, "env.yaml"))
if err != nil {
return err
}
var env interface{}
if err := yaml.Unmarshal(envText, &env); err != nil {
return err
}
if err := filepath.WalkDir(projectRoot, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.Name() == ".git" {
return fs.SkipDir
}
dir := filepath.Dir(path)
if strings.Contains(d.Name(), ".in.") {
fmt.Fprintf(os.Stderr, "template_secrets.go: processing %s\n", path)
input, err := os.ReadFile(path)
if err != nil {
return err
}
tmpl, err := template.New("").Funcs(sprig.TxtFuncMap()).Option("missingkey=error").Parse(string(input))
if err != nil {
return err
}
var output bytes.Buffer
if err := tmpl.Execute(&output, env); err != nil {
return err
}
if err := os.WriteFile(
filepath.Join(dir, strings.ReplaceAll(d.Name(), ".in.", ".out.")),
output.Bytes(), 0644,
); err != nil {
return err
}
}
return nil
}); err != nil {
return err
}
return nil
}
func main() {
if err := mainInternal(); err != nil {
fmt.Fprintf(os.Stderr, "template.go: %s\n", err.Error())
os.Exit(1)
}
}

590
yarn.lock
View File

@ -878,6 +878,32 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d"
integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==
"@kubernetes/client-node@^0.18.0":
version "0.18.0"
resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.18.0.tgz#b1002f3c19fb7509ce521ea78f500589f8e3e047"
integrity sha512-Mp6q0OkZQBp+HslIgvHYpsPJk8z6mch231QWtIZQHvs+PaTE6mkUfusYE8fNw3jMjru5mVO/JDz6PTjB9YT2rQ==
dependencies:
"@types/js-yaml" "^4.0.1"
"@types/node" "^10.12.0"
"@types/request" "^2.47.1"
"@types/ws" "^6.0.1"
byline "^5.0.0"
execa "5.0.0"
isomorphic-ws "^4.0.1"
js-yaml "^4.1.0"
jsonpath-plus "^0.19.0"
request "^2.88.0"
rfc4648 "^1.3.0"
shelljs "^0.8.5"
stream-buffers "^3.0.2"
tar "^6.1.11"
tmp-promise "^3.0.2"
tslib "^2.4.1"
underscore "^1.13.6"
ws "^7.3.1"
optionalDependencies:
openid-client "^5.3.0"
"@sentry/core@6.11.0":
version "6.11.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.11.0.tgz#40e94043afcf6407a109be26655c77832c64e740"
@ -946,11 +972,53 @@
"@sentry/types" "6.11.0"
tslib "^1.9.3"
"@types/caseless@*":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"
integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==
"@types/js-yaml@^4.0.1":
version "4.0.5"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138"
integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==
"@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
version "7.0.7"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
"@types/node@*":
version "18.11.17"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.17.tgz#5c009e1d9c38f4a2a9d45c0b0c493fe6cdb4bcb5"
integrity sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==
"@types/node@^10.12.0":
version "10.17.60"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==
"@types/request@^2.47.1":
version "2.48.8"
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c"
integrity sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==
dependencies:
"@types/caseless" "*"
"@types/node" "*"
"@types/tough-cookie" "*"
form-data "^2.5.0"
"@types/tough-cookie@*":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397"
integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==
"@types/ws@^6.0.1":
version "6.0.4"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.4.tgz#7797707c8acce8f76d8c34b370d4645b70421ff1"
integrity sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==
dependencies:
"@types/node" "*"
"@webassemblyjs/ast@1.9.0":
version "1.9.0"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
@ -1153,7 +1221,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2:
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5:
ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@ -1203,6 +1271,11 @@ aproba@^1.1.1:
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@ -1238,6 +1311,18 @@ asn1.js@^5.2.0:
minimalistic-assert "^1.0.0"
safer-buffer "^2.1.0"
asn1@~0.2.3:
version "0.2.6"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
assert@^1.1.1:
version "1.5.0"
resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
@ -1271,11 +1356,26 @@ async@^3.2.3:
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
atob@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==
aws4@^1.8.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
babel-loader@^8.2.2:
version "8.2.2"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81"
@ -1347,6 +1447,13 @@ base@^0.11.1:
mixin-deep "^1.2.0"
pascalcase "^0.1.1"
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
dependencies:
tweetnacl "^0.14.3"
big.js@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
@ -1545,6 +1652,11 @@ builtin-status-codes@^3.0.0:
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
byline@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
integrity sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==
bytes@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
@ -1599,6 +1711,11 @@ caniuse-lite@^1.0.30001219:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001237.tgz#4b7783661515b8e7151fc6376cfd97f0e427b9e5"
integrity sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw==
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@ -1655,6 +1772,11 @@ chownr@^1.1.1:
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
chownr@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
chrome-trace-event@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
@ -1724,6 +1846,13 @@ colorette@^1.2.1, colorette@^1.2.2:
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@ -1823,7 +1952,7 @@ core-js-compat@^3.14.0, core-js-compat@^3.9.1:
browserslist "^4.16.6"
semver "7.0.0"
core-util-is@~1.0.0:
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
@ -1911,6 +2040,13 @@ cyclist@^1.0.1:
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==
dependencies:
assert-plus "^1.0.0"
debounce@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
@ -1964,6 +2100,11 @@ define-property@^2.0.2:
is-descriptor "^1.0.2"
isobject "^3.0.1"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@ -2011,6 +2152,14 @@ duplexify@^3.4.2, duplexify@^3.6.0:
readable-stream "^2.0.0"
stream-shift "^1.0.0"
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -2147,6 +2296,21 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
execa@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376"
integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==
dependencies:
cross-spawn "^7.0.3"
get-stream "^6.0.0"
human-signals "^2.1.0"
is-stream "^2.0.0"
merge-stream "^2.0.0"
npm-run-path "^4.0.1"
onetime "^5.1.2"
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
execa@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
@ -2233,6 +2397,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
assign-symbols "^1.0.0"
is-extendable "^1.0.1"
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extglob@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
@ -2247,6 +2416,16 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==
extsprintf@^1.2.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
fast-deep-equal@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@ -2363,6 +2542,29 @@ for-in@^1.0.2:
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
form-data@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@ -2398,6 +2600,13 @@ fs-extra@^0.24.0:
path-is-absolute "^1.0.0"
rimraf "^2.2.8"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
dependencies:
minipass "^3.0.0"
fs-write-stream-atomic@^1.0.8:
version "1.0.10"
resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
@ -2455,6 +2664,13 @@ get-value@^2.0.3, get-value@^2.0.6:
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==
dependencies:
assert-plus "^1.0.0"
glob-parent@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
@ -2475,6 +2691,18 @@ glob-to-regexp@^0.3.0:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
glob@^7.0.0:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.1.3, glob@^7.1.4:
version "7.1.7"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
@ -2497,6 +2725,19 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==
har-validator@~5.1.3:
version "5.1.5"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
dependencies:
ajv "^6.12.3"
har-schema "^2.0.0"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@ -2594,6 +2835,15 @@ http-errors@1.8.1:
statuses ">= 1.5.0 < 2"
toidentifier "1.0.1"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
https-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
@ -2675,6 +2925,11 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
interpret@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
interpret@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
@ -2725,6 +2980,13 @@ is-core-module@^2.2.0:
dependencies:
has "^1.0.3"
is-core-module@^2.9.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==
dependencies:
has "^1.0.3"
is-data-descriptor@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@ -2812,6 +3074,11 @@ is-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@ -2844,6 +3111,16 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
isomorphic-ws@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc"
integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
jake@^10.8.5:
version "10.8.5"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46"
@ -2854,11 +3131,28 @@ jake@^10.8.5:
filelist "^1.0.1"
minimatch "^3.0.4"
jose@^4.10.0:
version "4.11.1"
resolved "https://registry.yarnpkg.com/jose/-/jose-4.11.1.tgz#8f7443549befe5bddcf4bae664a9cbc1a62da4fa"
integrity sha512-YRv4Tk/Wlug8qicwqFNFVEZSdbROCHRAC6qu/i0dyNKr5JQdoa2pIGoS04lLO/jXQX7Z9omoNewYIVIxqZBd9Q==
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@ -2879,6 +3173,16 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
@ -2900,11 +3204,26 @@ jsonfile@^2.1.0:
optionalDependencies:
graceful-fs "^4.1.6"
jsonpath-plus@^0.19.0:
version "0.19.0"
resolved "https://registry.yarnpkg.com/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz#b901e57607055933dc9a8bef0cc25160ee9dd64c"
integrity sha512-GSVwsrzW9LsA5lzsqe4CkuZ9wp+kxBb2GwNniaWzI2YFn5Ig42rSW8ZxVpWXaAfakXNrx5pgY5AbQq7kzX29kg==
jsonschema@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2"
integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==
jsprim@^1.2.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb"
integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.4.0"
verror "1.10.0"
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@ -3105,6 +3424,13 @@ mime-db@1.52.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
mime-types@~2.1.24:
version "2.1.31"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b"
@ -3112,13 +3438,6 @@ mime-types@~2.1.24:
dependencies:
mime-db "1.48.0"
mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
mime@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
@ -3146,16 +3465,40 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
minimatch@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.5:
minimist@^1.2.0, minimist@^1.2.5:
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
minipass@^3.0.0:
version "3.3.6"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a"
integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==
dependencies:
yallist "^4.0.0"
minipass@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.0.0.tgz#7cebb0f9fa7d56f0c5b17853cbe28838a8dbbd3b"
integrity sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==
dependencies:
yallist "^4.0.0"
minizlib@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
dependencies:
minipass "^3.0.0"
yallist "^4.0.0"
mississippi@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
@ -3187,6 +3530,11 @@ mkdirp@^0.5.1, mkdirp@^0.5.3:
dependencies:
minimist "^1.2.5"
mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
monaco-editor-webpack-plugin@1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.9.0.tgz#5b547281b9f404057dc5d8c5722390df9ac90be6"
@ -3326,6 +3674,11 @@ npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@ -3340,6 +3693,11 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
object-hash@^2.0.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5"
integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
@ -3369,6 +3727,11 @@ object.pick@^1.3.0:
dependencies:
isobject "^3.0.1"
oidc-token-hash@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz#ae6beec3ec20f0fd885e5400d175191d6e2f10c6"
integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
@ -3390,6 +3753,16 @@ onetime@^5.1.2:
dependencies:
mimic-fn "^2.1.0"
openid-client@^5.3.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.3.1.tgz#69a5fa7d2b5ad479032f576852d40b4d4435488a"
integrity sha512-RLfehQiHch9N6tRWNx68cicf3b1WR0x74bJWHRc25uYIbSRwjxYcTFaRnzbbpls5jroLAaB/bFIodTgA5LJMvw==
dependencies:
jose "^4.10.0"
lru-cache "^6.0.0"
object-hash "^2.0.1"
oidc-token-hash "^5.0.1"
os-browserify@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
@ -3511,7 +3884,7 @@ path-key@^3.0.0, path-key@^3.1.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-parse@^1.0.6:
path-parse@^1.0.6, path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
@ -3532,6 +3905,11 @@ pbkdf2@^3.0.3:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
picomatch@^2.0.4, picomatch@^2.2.1:
version "2.3.0"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
@ -3651,6 +4029,11 @@ prr@~1.0.1:
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
psl@^1.1.28:
version "1.9.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
public-encrypt@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
@ -3698,7 +4081,7 @@ punycode@^1.2.4:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
punycode@^2.1.0:
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
@ -3708,6 +4091,11 @@ qs@6.9.7:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe"
integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==
qs@~6.5.2:
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
querystring-es3@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@ -3786,6 +4174,13 @@ readdirp@~3.5.0:
dependencies:
picomatch "^2.2.1"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==
dependencies:
resolve "^1.1.6"
rechoir@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca"
@ -3864,6 +4259,32 @@ repeat-string@^1.6.1:
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
request@^2.88.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
caseless "~0.12.0"
combined-stream "~1.0.6"
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
har-validator "~5.1.3"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
oauth-sign "~0.9.0"
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "~2.5.0"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
resolve-cwd@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
@ -3881,6 +4302,15 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
resolve@^1.1.6:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
dependencies:
is-core-module "^2.9.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^1.14.2, resolve@^1.9.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
@ -3894,6 +4324,11 @@ ret@~0.1.10:
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
rfc4648@^1.3.0:
version "1.5.2"
resolved "https://registry.yarnpkg.com/rfc4648/-/rfc4648-1.5.2.tgz#cf5dac417dd83e7f4debf52e3797a723c1373383"
integrity sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg==
rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
@ -3901,6 +4336,13 @@ rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3:
dependencies:
glob "^7.1.3"
rimraf@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
@ -3933,7 +4375,7 @@ safe-regex@^1.1.0:
dependencies:
ret "~0.1.10"
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0:
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@ -4075,6 +4517,15 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shelljs@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
signal-exit@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
@ -4161,6 +4612,21 @@ split-string@^3.0.1, split-string@^3.0.2:
dependencies:
extend-shallow "^3.0.0"
sshpk@^1.7.0:
version "1.17.0"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5"
integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
bcrypt-pbkdf "^1.0.0"
dashdash "^1.12.0"
ecc-jsbn "~0.1.1"
getpass "^0.1.1"
jsbn "~0.1.0"
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
ssri@^6.0.1:
version "6.0.2"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
@ -4189,6 +4655,11 @@ stream-browserify@^2.0.1:
inherits "~2.0.1"
readable-stream "^2.0.2"
stream-buffers@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521"
integrity sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==
stream-each@^1.1.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae"
@ -4261,11 +4732,28 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
tapable@^1.0.0, tapable@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
tar@^6.1.11:
version "6.1.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b"
integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
minipass "^4.0.0"
minizlib "^2.1.1"
mkdirp "^1.0.3"
yallist "^4.0.0"
tdigest@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.1.tgz#2e3cb2c39ea449e55d1e6cd91117accca4588021"
@ -4312,6 +4800,20 @@ timers-browserify@^2.0.4:
dependencies:
setimmediate "^1.0.4"
tmp-promise@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7"
integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==
dependencies:
tmp "^0.2.0"
tmp@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
dependencies:
rimraf "^3.0.0"
to-arraybuffer@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
@ -4359,16 +4861,41 @@ toidentifier@1.0.1:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
dependencies:
psl "^1.1.28"
punycode "^2.1.1"
tslib@^1.9.3:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
@ -4382,6 +4909,11 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
underscore@^1.13.6:
version "1.13.6"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441"
integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==
unicode-canonical-property-names-ecmascript@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
@ -4422,6 +4954,11 @@ unique-filename@^1.1.1:
dependencies:
unique-slug "^2.0.0"
unique-names-generator@^4.7.1:
version "4.7.1"
resolved "https://registry.yarnpkg.com/unique-names-generator/-/unique-names-generator-4.7.1.tgz#966407b12ba97f618928f77322cfac8c80df5597"
integrity sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==
unique-slug@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c"
@ -4496,6 +5033,11 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
@ -4511,6 +5053,15 @@ vary@~1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
vm-browserify@^1.0.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
@ -4660,6 +5211,11 @@ ws@^5.2.0:
dependencies:
async-limiter "~1.0.0"
ws@^7.3.1:
version "7.5.9"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"