@vfarcic/dot-ai 0.103.0 → 0.104.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/core/nushell-runtime.d.ts +39 -0
- package/dist/core/nushell-runtime.d.ts.map +1 -0
- package/dist/core/nushell-runtime.js +103 -0
- package/dist/core/platform-operations.d.ts +76 -0
- package/dist/core/platform-operations.d.ts.map +1 -0
- package/dist/core/platform-operations.js +317 -0
- package/dist/interfaces/mcp.d.ts.map +1 -1
- package/dist/interfaces/mcp.js +9 -1
- package/dist/tools/build-platform.d.ts +25 -0
- package/dist/tools/build-platform.d.ts.map +1 -0
- package/dist/tools/build-platform.js +277 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -1
- package/dist/tools/version.d.ts +7 -0
- package/dist/tools/version.d.ts.map +1 -1
- package/dist/tools/version.js +34 -5
- package/package.json +3 -2
- package/prompts/map-intent-to-operation.md +104 -0
- package/prompts/parse-script-operations.md +72 -0
- package/scripts/ack.nu +195 -0
- package/scripts/anthropic.nu +24 -0
- package/scripts/argo-workflows.nu +47 -0
- package/scripts/argocd.nu +85 -0
- package/scripts/aso.nu +74 -0
- package/scripts/atlas.nu +15 -0
- package/scripts/backstage.nu +349 -0
- package/scripts/cert-manager.nu +13 -0
- package/scripts/cnpg.nu +14 -0
- package/scripts/common.nu +116 -0
- package/scripts/crossplane.nu +718 -0
- package/scripts/dot.nu +32 -0
- package/scripts/external-secrets.nu +110 -0
- package/scripts/gatekeeper.nu +19 -0
- package/scripts/github.nu +42 -0
- package/scripts/image.nu +67 -0
- package/scripts/ingress.nu +149 -0
- package/scripts/kro.nu +11 -0
- package/scripts/kubernetes.nu +609 -0
- package/scripts/kubevela.nu +22 -0
- package/scripts/kyverno.nu +16 -0
- package/scripts/mcp.nu +139 -0
- package/scripts/port.nu +71 -0
- package/scripts/prometheus.nu +21 -0
- package/scripts/registry.nu +55 -0
- package/scripts/storage.nu +210 -0
- package/scripts/tests.nu +12 -0
- package/scripts/toolhive.nu +21 -0
- package/scripts/velero.nu +45 -0
package/scripts/mcp.nu
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env nu
|
|
2
|
+
|
|
3
|
+
# Creates the MCP servers configuration file.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# > main apply mcp
|
|
7
|
+
# > main apply mcp --location my-custom-path.json
|
|
8
|
+
# > main apply mcp --location [ my-custom-path.json, another-path.json ]
|
|
9
|
+
# > main apply mcp --memory-file-path /custom/memory.json --anthropic-api-key XYZ --github-token ABC
|
|
10
|
+
# > main apply mcp --enable-playwright
|
|
11
|
+
# > main apply mcp --enable-context7
|
|
12
|
+
# > main apply mcp --enable-git
|
|
13
|
+
# > main apply mcp --enable-dot-ai --kubeconfig /path/to/kubeconfig
|
|
14
|
+
# > main apply mcp --enable-dot-ai --dot-ai-version 1.2.3
|
|
15
|
+
# > main apply mcp --enable-taskmaster
|
|
16
|
+
# > main apply mcp --enable-memory
|
|
17
|
+
# > main apply mcp --enable-github
|
|
18
|
+
#
|
|
19
|
+
def --env "main apply mcp" [
|
|
20
|
+
--location: list<string> = [".mcp.json"], # Path(s) where the MCP servers configuration file will be created (e.g., `".cursor/mcp.json", ".roo/mcp.json", ".vscode/mcp.json", "mcp.json"`)
|
|
21
|
+
--memory-file-path: string = "", # Path to the memory file for the memory MCP server. If empty, defaults to an absolute path for 'memory.json' in CWD.
|
|
22
|
+
--anthropic-api-key: string = "", # Anthropic API key for the taskmaster-ai MCP server. If empty, $env.ANTHROPIC_API_KEY is used if set.
|
|
23
|
+
--github-token: string = "", # GitHub Personal Access Token for the github MCP server. If empty, $env.GITHUB_TOKEN is used if set.
|
|
24
|
+
--kubeconfig: string = "", # Path to kubeconfig file for dot-ai MCP server. If empty, $env.KUBECONFIG is used if set.
|
|
25
|
+
--dot-ai-version: string = "latest", # Version of dot-ai MCP server to use. Defaults to 'latest'
|
|
26
|
+
--enable-playwright = false, # Enable Playwright MCP server for browser automation
|
|
27
|
+
--enable-context7 = false, # Enable Context7 MCP server
|
|
28
|
+
--enable-git = false, # Enable Git MCP server
|
|
29
|
+
--enable-dot-ai = false, # Enable dot-ai MCP server
|
|
30
|
+
--enable-taskmaster = false, # Enable taskmaster-ai MCP server (requires Anthropic API key)
|
|
31
|
+
--enable-memory = false, # Enable memory MCP server
|
|
32
|
+
--enable-github = false # Enable GitHub MCP server (requires GitHub token)
|
|
33
|
+
] {
|
|
34
|
+
let resolved_memory_file_path = if $memory_file_path == "" {
|
|
35
|
+
(pwd) | path join "memory.json" | path expand
|
|
36
|
+
} else {
|
|
37
|
+
$memory_file_path
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let resolved_anthropic_api_key = if $anthropic_api_key != "" {
|
|
41
|
+
$anthropic_api_key
|
|
42
|
+
} else if ("ANTHROPIC_API_KEY" in $env) {
|
|
43
|
+
$env.ANTHROPIC_API_KEY
|
|
44
|
+
} else {
|
|
45
|
+
""
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let resolved_github_token = if $github_token != "" {
|
|
49
|
+
$github_token
|
|
50
|
+
} else if ("GITHUB_TOKEN" in $env) {
|
|
51
|
+
$env.GITHUB_TOKEN
|
|
52
|
+
} else {
|
|
53
|
+
""
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let resolved_kubeconfig = if $kubeconfig != "" {
|
|
57
|
+
$kubeconfig
|
|
58
|
+
} else if ("KUBECONFIG" in $env) {
|
|
59
|
+
$env.KUBECONFIG
|
|
60
|
+
} else {
|
|
61
|
+
""
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
mut mcp_servers_map = {}
|
|
65
|
+
|
|
66
|
+
if $enable_memory {
|
|
67
|
+
$mcp_servers_map = $mcp_servers_map | upsert "memory" {
|
|
68
|
+
command: "npx",
|
|
69
|
+
args: ["-y", "@modelcontextprotocol/server-memory"],
|
|
70
|
+
env: {
|
|
71
|
+
MEMORY_FILE_PATH: $resolved_memory_file_path
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if $enable_context7 {
|
|
77
|
+
$mcp_servers_map = $mcp_servers_map | upsert "context7" {
|
|
78
|
+
command: "npx",
|
|
79
|
+
args: ["-y", "@upstash/context7-mcp"]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if $enable_taskmaster and $resolved_anthropic_api_key != "" {
|
|
84
|
+
$mcp_servers_map = $mcp_servers_map | upsert "taskmaster" {
|
|
85
|
+
command: "npx",
|
|
86
|
+
args: ["-y", "--package=task-master-ai", "task-master-ai"],
|
|
87
|
+
env: {
|
|
88
|
+
ANTHROPIC_API_KEY: $resolved_anthropic_api_key
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if $enable_github and $resolved_github_token != "" {
|
|
94
|
+
$mcp_servers_map = $mcp_servers_map | upsert "github" {
|
|
95
|
+
command: "docker",
|
|
96
|
+
args: ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"],
|
|
97
|
+
env: {
|
|
98
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: $resolved_github_token
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if $enable_playwright {
|
|
104
|
+
$mcp_servers_map = $mcp_servers_map | upsert "playwright" {
|
|
105
|
+
command: "npx",
|
|
106
|
+
args: ["-y", "@playwright/mcp@latest"]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if $enable_git {
|
|
111
|
+
$mcp_servers_map = $mcp_servers_map | upsert "git" {
|
|
112
|
+
command: "uvx",
|
|
113
|
+
args: ["mcp-server-git"]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if $enable_dot_ai and $resolved_anthropic_api_key != "" and $resolved_kubeconfig != "" {
|
|
118
|
+
$mcp_servers_map = $mcp_servers_map | upsert "dot-ai" {
|
|
119
|
+
command: "npx",
|
|
120
|
+
args: ["-y", $"--package=@vfarcic/dot-ai@($dot_ai_version)", "dot-ai-mcp"],
|
|
121
|
+
env: {
|
|
122
|
+
KUBECONFIG: $resolved_kubeconfig,
|
|
123
|
+
DOT_AI_SESSION_DIR: "./tmp/sessions"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let config_record = { mcpServers: $mcp_servers_map }
|
|
129
|
+
|
|
130
|
+
for $output_location in $location {
|
|
131
|
+
let parent_dir = $output_location | path dirname
|
|
132
|
+
if not ($parent_dir | path exists) {
|
|
133
|
+
mkdir $parent_dir
|
|
134
|
+
print $"Created directory: ($parent_dir)"
|
|
135
|
+
}
|
|
136
|
+
$config_record | to json --indent 2 | save -f $output_location
|
|
137
|
+
print $"MCP servers configuration file created at: ($output_location)"
|
|
138
|
+
}
|
|
139
|
+
}
|
package/scripts/port.nu
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env nu
|
|
2
|
+
|
|
3
|
+
# Installs Port.io for software catalog management
|
|
4
|
+
#
|
|
5
|
+
# Examples:
|
|
6
|
+
# > main apply port myuser my-repo
|
|
7
|
+
def "main apply port" [
|
|
8
|
+
github_user: string
|
|
9
|
+
github_repo: string
|
|
10
|
+
--port-client-id: string, # Port Client ID (optional, falls back to PORT_CLIENT_ID env var)
|
|
11
|
+
--port-client-secret: string # Port Client Secret (optional, falls back to PORT_CLIENT_SECRET env var)
|
|
12
|
+
] {
|
|
13
|
+
|
|
14
|
+
start "https://getport.io"
|
|
15
|
+
|
|
16
|
+
print $"
|
|
17
|
+
(ansi yellow_bold)Sign Up(ansi reset) \(if not already registered\) and (ansi yellow_bold)Log In(ansi reset) to Port.
|
|
18
|
+
Press any key to continue.
|
|
19
|
+
"
|
|
20
|
+
input
|
|
21
|
+
|
|
22
|
+
mut client_id = $port_client_id
|
|
23
|
+
if ($client_id | is-empty) and ("PORT_CLIENT_ID" in $env) {
|
|
24
|
+
$client_id = $env.PORT_CLIENT_ID
|
|
25
|
+
} else if ($client_id | is-empty) {
|
|
26
|
+
error make { msg: "Port Client ID required via --port-client-id parameter or PORT_CLIENT_ID environment variable" }
|
|
27
|
+
}
|
|
28
|
+
$"export PORT_CLIENT_ID=($client_id)\n"
|
|
29
|
+
| save --append .env
|
|
30
|
+
|
|
31
|
+
mut client_secret = $port_client_secret
|
|
32
|
+
if ($client_secret | is-empty) and ("PORT_CLIENT_SECRET" in $env) {
|
|
33
|
+
$client_secret = $env.PORT_CLIENT_SECRET
|
|
34
|
+
} else if ($client_secret | is-empty) {
|
|
35
|
+
error make { msg: "Port Client Secret required via --port-client-secret parameter or PORT_CLIENT_SECRET environment variable" }
|
|
36
|
+
}
|
|
37
|
+
$"export PORT_CLIENT_SECRET=($client_secret)\n"
|
|
38
|
+
| save --append .env
|
|
39
|
+
|
|
40
|
+
print $"
|
|
41
|
+
Install (ansi green_bold)Port's GitHub app(ansi reset).
|
|
42
|
+
Open https://docs.getport.io/build-your-software-catalog/sync-data-to-catalog/git/github/#installation for more information.
|
|
43
|
+
Press any key to continue.
|
|
44
|
+
"
|
|
45
|
+
input
|
|
46
|
+
|
|
47
|
+
(
|
|
48
|
+
helm upgrade --install port-k8s-exporter port-k8s-exporter
|
|
49
|
+
--repo https://port-labs.github.io/helm-charts
|
|
50
|
+
--namespace port-k8s-exporter --create-namespace
|
|
51
|
+
--set $"secret.secrets.portClientId=($client_id)"
|
|
52
|
+
--set $"secret.secrets.portClientSecret=($client_secret)"
|
|
53
|
+
--set stateKey="k8s-exporter"
|
|
54
|
+
--set createDefaultResources=false
|
|
55
|
+
--set "extraEnv[0].name"="dot"
|
|
56
|
+
--set "extraEnv[0].value"=dot
|
|
57
|
+
--wait
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# Guides cleanup of Port.io resources
|
|
63
|
+
def "main delete port" [] {
|
|
64
|
+
|
|
65
|
+
print $"
|
|
66
|
+
Delete all items from the (ansi yellow_bold)Catalog(ansi reset), (ansi yellow_bold)Self-service(ansi reset), and (ansi yellow_bold)Builder > Data model(ansi reset) pages in Port's Web UI.
|
|
67
|
+
Press any key to continue.
|
|
68
|
+
"
|
|
69
|
+
input
|
|
70
|
+
|
|
71
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env nu
|
|
2
|
+
|
|
3
|
+
def apply_prometheus [ingress_class: string, ingress_host: string] {
|
|
4
|
+
|
|
5
|
+
open values-prometheus.yaml
|
|
6
|
+
| upsert grafana.ingress.ingressClassName $ingress_class
|
|
7
|
+
| upsert grafana.ingress.hosts.0 $"grafana.($ingress_host)"
|
|
8
|
+
| upsert prometheus.ingress.ingressClassName $ingress_class
|
|
9
|
+
| upsert prometheus.ingress.hosts.0 $"prometheus.($ingress_host)"
|
|
10
|
+
| save values-prometheus.yaml --force
|
|
11
|
+
|
|
12
|
+
(
|
|
13
|
+
helm upgrade --install
|
|
14
|
+
kube-prometheus-stack kube-prometheus-stack
|
|
15
|
+
--repo https://prometheus-community.github.io/helm-charts
|
|
16
|
+
--values values-prometheus.yaml
|
|
17
|
+
--namespace prometheus-system --create-namespace
|
|
18
|
+
--wait
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env nu
|
|
2
|
+
|
|
3
|
+
# Returns registry information.
|
|
4
|
+
#
|
|
5
|
+
# Parameters:
|
|
6
|
+
# --registry-server: Container registry server (optional, falls back to REGISTRY_SERVER env var)
|
|
7
|
+
# --registry-user: Container registry user (optional, falls back to REGISTRY_USER env var)
|
|
8
|
+
# --registry-email: Container registry email (optional, falls back to REGISTRY_EMAIL env var)
|
|
9
|
+
# --registry-password: Container registry password/token (optional, falls back to REGISTRY_PASSWORD env var)
|
|
10
|
+
#
|
|
11
|
+
# Example: `{server: "my-server", user: "my-user", email: "my-email", password: "my-password"}`
|
|
12
|
+
def --env "main get registry" [
|
|
13
|
+
--registry-server: string,
|
|
14
|
+
--registry-user: string,
|
|
15
|
+
--registry-email: string,
|
|
16
|
+
--registry-password: string
|
|
17
|
+
]: [
|
|
18
|
+
string -> record
|
|
19
|
+
] {
|
|
20
|
+
|
|
21
|
+
mut server = $registry_server
|
|
22
|
+
if ($server | is-empty) and ("REGISTRY_SERVER" in $env) {
|
|
23
|
+
$server = $env.REGISTRY_SERVER
|
|
24
|
+
} else if ($server | is-empty) {
|
|
25
|
+
error make { msg: "Registry server required via --registry-server parameter or REGISTRY_SERVER environment variable" }
|
|
26
|
+
}
|
|
27
|
+
$"export REGISTRY_SERVER=($server)\n" | save --append .env
|
|
28
|
+
|
|
29
|
+
mut user = $registry_user
|
|
30
|
+
if ($user | is-empty) and ("REGISTRY_USER" in $env) {
|
|
31
|
+
$user = $env.REGISTRY_USER
|
|
32
|
+
} else if ($user | is-empty) {
|
|
33
|
+
error make { msg: "Registry user required via --registry-user parameter or REGISTRY_USER environment variable" }
|
|
34
|
+
}
|
|
35
|
+
$"export REGISTRY_USER=($user)\n" | save --append .env
|
|
36
|
+
|
|
37
|
+
mut email = $registry_email
|
|
38
|
+
if ($email | is-empty) and ("REGISTRY_EMAIL" in $env) {
|
|
39
|
+
$email = $env.REGISTRY_EMAIL
|
|
40
|
+
} else if ($email | is-empty) {
|
|
41
|
+
error make { msg: "Registry email required via --registry-email parameter or REGISTRY_EMAIL environment variable" }
|
|
42
|
+
}
|
|
43
|
+
$"export REGISTRY_EMAIL=($email)\n" | save --append .env
|
|
44
|
+
|
|
45
|
+
mut password = $registry_password
|
|
46
|
+
if ($password | is-empty) and ("REGISTRY_PASSWORD" in $env) {
|
|
47
|
+
$password = $env.REGISTRY_PASSWORD
|
|
48
|
+
} else if ($password | is-empty) {
|
|
49
|
+
error make { msg: "Registry password required via --registry-password parameter or REGISTRY_PASSWORD environment variable" }
|
|
50
|
+
}
|
|
51
|
+
$"export REGISTRY_PASSWORD=($password)\n" | save --append .env
|
|
52
|
+
|
|
53
|
+
{server: $server, user: $user, email: $email, password: $password}
|
|
54
|
+
|
|
55
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env nu
|
|
2
|
+
|
|
3
|
+
# Creates cloud storage resources based on the specified provider
|
|
4
|
+
#
|
|
5
|
+
# Returns:
|
|
6
|
+
# A record with the storage bucket name
|
|
7
|
+
def create_storage [provider: string, auth = true] {
|
|
8
|
+
|
|
9
|
+
let bucket = $"dot-(date now | format date "%Y%m%d%H%M%S")"
|
|
10
|
+
$"export STORAGE_NAME=($bucket)\n" | save --append .env
|
|
11
|
+
|
|
12
|
+
if $provider == "aws" {
|
|
13
|
+
|
|
14
|
+
(
|
|
15
|
+
aws s3api create-bucket --bucket $bucket
|
|
16
|
+
--region us-east-1
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
aws iam create-user --user-name velero
|
|
20
|
+
|
|
21
|
+
(
|
|
22
|
+
aws iam put-user-policy --user-name velero
|
|
23
|
+
--policy-name velero
|
|
24
|
+
--policy-document file://aws-storage-policy.json
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
let access_key_id = (
|
|
28
|
+
aws iam create-access-key --user-name velero
|
|
29
|
+
| from json
|
|
30
|
+
| get AccessKey.AccessKeyId
|
|
31
|
+
)
|
|
32
|
+
$"export STORAGE_ACCESS_KEY_ID=($access_key_id)\n"
|
|
33
|
+
| save --append .env
|
|
34
|
+
|
|
35
|
+
} else if $provider == "google" {
|
|
36
|
+
|
|
37
|
+
if $auth {
|
|
38
|
+
gcloud auth login
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
(
|
|
42
|
+
gcloud storage buckets create $"gs://($bucket)"
|
|
43
|
+
--project $env.PROJECT_ID --location us-east1
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
(
|
|
47
|
+
gcloud iam service-accounts create velero
|
|
48
|
+
--project $env.PROJECT_ID --display-name "Velero"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
let sa_email = $"velero@($env.PROJECT_ID).iam.gserviceaccount.com"
|
|
52
|
+
|
|
53
|
+
(
|
|
54
|
+
gcloud iam roles create velero.server
|
|
55
|
+
--project $env.PROJECT_ID
|
|
56
|
+
--file google-permissions.yaml
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
(
|
|
60
|
+
gcloud projects add-iam-policy-binding $env.PROJECT_ID
|
|
61
|
+
--member $"serviceAccount:($sa_email)"
|
|
62
|
+
--role $"projects/($env.PROJECT_ID)/roles/velero.server"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
(
|
|
66
|
+
gsutil iam ch
|
|
67
|
+
$"serviceAccount:($sa_email):objectAdmin"
|
|
68
|
+
$"gs://($bucket)"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
(
|
|
72
|
+
gcloud iam service-accounts keys create
|
|
73
|
+
google-creds.json --iam-account $sa_email
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
} else if $provider == "azure" {
|
|
77
|
+
|
|
78
|
+
let sa_id = $"velero(uuidgen | cut -d '-' -f5 | tr '[A-Z]' '[a-z]')"
|
|
79
|
+
$"export AZURE_SA_ID=($sa_id)\n" | save --append .env
|
|
80
|
+
|
|
81
|
+
(
|
|
82
|
+
az storage account create
|
|
83
|
+
--name $sa_id
|
|
84
|
+
--resource-group $env.RESOURCE_GROUP
|
|
85
|
+
--sku Standard_GRS --encryption-services blob
|
|
86
|
+
--https-only true --min-tls-version TLS1_2
|
|
87
|
+
--kind BlobStorage --access-tier Hot
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
(
|
|
91
|
+
az storage container create --name velero
|
|
92
|
+
--public-access off --account-name $sa_id
|
|
93
|
+
--resource-group $env.RESOURCE_GROUP
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
let subscription_id = (az account list
|
|
97
|
+
--query '[?isDefault].id' --output tsv)
|
|
98
|
+
|
|
99
|
+
open azure-permissions.json
|
|
100
|
+
| upsert AssignableScopes.0 $"/subscriptions/($subscription_id)"
|
|
101
|
+
| save azure-permissions.json --force
|
|
102
|
+
|
|
103
|
+
(
|
|
104
|
+
az role definition create
|
|
105
|
+
--role-definition azure-permissions.json
|
|
106
|
+
--resource-group $env.RESOURCE_GROUP
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
let tenant_id = (az account list
|
|
110
|
+
--query '[?isDefault].tenantId' --output tsv)
|
|
111
|
+
|
|
112
|
+
let client_secret = (az ad sp create-for-rbac
|
|
113
|
+
--name velero --role Velero --query 'password'
|
|
114
|
+
--output tsv
|
|
115
|
+
--scopes $"/subscriptions/($subscription_id)"
|
|
116
|
+
--resource-group $env.RESOURCE_GROUP
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
let client_id = (az ad sp list --display-name "velero"
|
|
120
|
+
--query '[0].appId' --output tsv)
|
|
121
|
+
$"export AZURE_CLIENT_ID=($client_id)\n"
|
|
122
|
+
| save --append .env
|
|
123
|
+
|
|
124
|
+
$"AZURE_SUBSCRIPTION_ID=($subscription_id)
|
|
125
|
+
AZURE_TENANT_ID=($tenant_id)
|
|
126
|
+
AZURE_CLIENT_ID=($client_id)
|
|
127
|
+
AZURE_CLIENT_SECRET=($client_secret)
|
|
128
|
+
AZURE_RESOURCE_GROUP=($env.RESOURCE_GROUP)
|
|
129
|
+
AZURE_CLOUD_NAME=AzurePublicCloud" | save azure-creds.env --force
|
|
130
|
+
|
|
131
|
+
} else {
|
|
132
|
+
|
|
133
|
+
print $"(ansi red_bold)($provider)(ansi reset) is not a supported."
|
|
134
|
+
exit 1
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
{name: $bucket}
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# Destroys cloud storage resources created for the specified provider
|
|
143
|
+
def destroy_storage [provider: string, storage_name: string, delete_project = true] {
|
|
144
|
+
|
|
145
|
+
if $provider == "aws" {
|
|
146
|
+
|
|
147
|
+
do --ignore-errors {
|
|
148
|
+
|
|
149
|
+
(
|
|
150
|
+
aws iam delete-access-key --user-name velero
|
|
151
|
+
--access-key-id $env.STORAGE_ACCESS_KEY_ID
|
|
152
|
+
--region us-east-1
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
(
|
|
156
|
+
aws iam delete-user-policy --user-name velero
|
|
157
|
+
--policy-name velero
|
|
158
|
+
--region us-east-1
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
aws iam delete-user --user-name velero
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
(
|
|
166
|
+
aws s3 rm $"s3://($storage_name)" --recursive
|
|
167
|
+
--include "*"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
(
|
|
171
|
+
aws s3api delete-bucket --bucket $storage_name
|
|
172
|
+
--region us-east-1
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
} else if $provider == "google" {
|
|
176
|
+
|
|
177
|
+
(
|
|
178
|
+
gcloud storage rm $"gs://($storage_name)" --recursive
|
|
179
|
+
--project $env.PROJECT_ID
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
if $delete_project {
|
|
183
|
+
gcloud projects delete $env.PROJECT_ID --quiet
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
} else if $provider == "azure" {
|
|
187
|
+
|
|
188
|
+
(
|
|
189
|
+
az storage container delete --name velero
|
|
190
|
+
--account-name $env.AZURE_SA_ID
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
(
|
|
194
|
+
az storage account delete
|
|
195
|
+
--name $env.AZURE_SA_ID
|
|
196
|
+
--resource-group $env.RESOURCE_GROUP --yes
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
az ad sp delete --id $env.AZURE_CLIENT_ID
|
|
200
|
+
|
|
201
|
+
az role definition delete --name Velero
|
|
202
|
+
|
|
203
|
+
} else {
|
|
204
|
+
|
|
205
|
+
print $"(ansi red_bold)($provider)(ansi reset) is not a supported."
|
|
206
|
+
exit 1
|
|
207
|
+
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
}
|
package/scripts/tests.nu
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env nu
|
|
2
|
+
|
|
3
|
+
# Installs Stacklock Toolhive
|
|
4
|
+
#
|
|
5
|
+
# Examples:
|
|
6
|
+
# > main apply toolhive
|
|
7
|
+
def "main apply toolhive" [] {
|
|
8
|
+
|
|
9
|
+
(
|
|
10
|
+
helm upgrade --install toolhive-operator-crds
|
|
11
|
+
oci://ghcr.io/stacklok/toolhive/toolhive-operator-crds
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
(
|
|
15
|
+
helm upgrade --install toolhive-operator
|
|
16
|
+
oci://ghcr.io/stacklok/toolhive/toolhive-operator
|
|
17
|
+
--namespace toolhive-system --create-namespace
|
|
18
|
+
--wait
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env nu
|
|
2
|
+
|
|
3
|
+
# Installs Velero backup and restore solution for Kubernetes with provider-specific configuration
|
|
4
|
+
def apply_velero [provider: string, storage_name: string] {
|
|
5
|
+
|
|
6
|
+
if $provider == "aws" {
|
|
7
|
+
|
|
8
|
+
(
|
|
9
|
+
velero install --provider aws
|
|
10
|
+
--plugins velero/velero-plugin-for-aws:v1.10.0
|
|
11
|
+
--bucket $storage_name
|
|
12
|
+
--backup-location-config region=us-east-1
|
|
13
|
+
--snapshot-location-config region=us-east-1
|
|
14
|
+
--secret-file ./aws-creds.conf --output yaml
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
} else if $provider == "google" {
|
|
18
|
+
|
|
19
|
+
(
|
|
20
|
+
velero install --provider gcp
|
|
21
|
+
--plugins velero/velero-plugin-for-gcp:v1.11.0
|
|
22
|
+
--bucket $storage_name
|
|
23
|
+
--secret-file ./google-creds.json --output yaml
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
} else if $provider == "azure" {
|
|
27
|
+
|
|
28
|
+
(
|
|
29
|
+
velero install --provider azure
|
|
30
|
+
--plugins velero/velero-plugin-for-microsoft-azure:v1.11.0
|
|
31
|
+
--bucket $storage_name
|
|
32
|
+
--service-account-name velero
|
|
33
|
+
--pod-labels azure.workload.identity/use=true
|
|
34
|
+
--secret-file azure-creds.env
|
|
35
|
+
--backup-location-config $"useAAD='true',resourceGroup=($env.RESOURCE_GROUP),storageAccount=($env.AZURE_SA_ID)"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
} else {
|
|
39
|
+
|
|
40
|
+
print $"(ansi red_bold)($provider)(ansi reset) is not a supported."
|
|
41
|
+
exit 1
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
}
|