commit 0d10d42442aefc11fdb2c394cf4e5d2eb74495c2 Author: allanice001 Date: Sun Nov 2 13:19:30 2025 +0000 feat: sdk migration in progress diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de18b88 --- /dev/null +++ b/.gitignore @@ -0,0 +1,136 @@ +# Created by https://www.toptal.com/developers/gitignore/api/go,react,intellij+all +# Edit at https://www.toptal.com/developers/gitignore?templates=go,react,intellij+all + +### Go ### +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work + +### Intellij+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij+all Patch ### +# Ignore everything but code style settings and run configurations +# that are supposed to be shared within teams. + +.idea/* + +!.idea/codeStyles +!.idea/runConfigurations + +### react ### +.DS_* +*.log +logs +**/*.backup.* +**/*.back.* + +node_modules +bower_components + +*.sublime* + +psd +thumb +sketch + +# End of https://www.toptal.com/developers/gitignore/api/go,react,intellij+all + +.env +config.yaml +go_*_WhiteSpaceConflict/ +notes.txt \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5e3da28 --- /dev/null +++ b/Makefile @@ -0,0 +1,277 @@ +# --- variables --- +GOCMD ?= go +GOINSTALL := $(GOCMD) install +BIN ?= autoglue +MAIN ?= main.go +UI_DIR ?= ui +UI_DEST_DIR ?= internal/web + +# Module path (used for ldflags to internal/version) +GIT_HOST ?= github.com +GIT_USER ?= glueops +MODULE_PATH ?= $(GIT_HOST)/$(GIT_USER)/$(BIN) + +# SDK / module settings (Go) +SDK_REPO ?= $(BIN)-sdk # repo name used for module path +SDK_OUTDIR ?= sdk/go # output directory (inside repo) +SDK_PKG ?= ${BIN} # package name inside the SDK + +UI_SSG_ROUTES ?= /,/login,/docs,/pricing + +# Go versioning (go.mod uses major.minor; you’re on 1.25.3) +GO_VERSION ?= 1.25.3 + +# SDK / package settings (TypeScript) +SDK_TS_OUTDIR ?= sdk/ts +SDK_TS_GEN ?= typescript-fetch +SDK_TS_NPM_NAME ?= @glueops/$(SDK_REPO) +SDK_TS_NPM_VER ?= 0.1.0 +SDK_TS_DIR := $(abspath $(SDK_TS_OUTDIR)) +SDK_TS_PROPS ?= supportsES6=true,typescriptThreePlus=true,useSingleRequestParameter=true,withSeparateModelsAndApi=true,modelPropertyNaming=original,enumPropertyNaming=original,useUnionTypes=true +SDK_TS_PROPS_FLAGS := $(foreach p,$(subst , ,$(SDK_TS_PROPS)),-p $(p)) + +# Path for vendored UI SDK (absolute, path-safe) +SDK_TS_UI_OUTDIR ?= ui/src/sdk +SDK_TS_UI_DIR := $(abspath $(SDK_TS_UI_OUTDIR)) + +SWAG := $(shell command -v swag 2>/dev/null) +GMU := $(shell command -v go-mod-upgrade 2>/dev/null) +YARN := $(shell command -v yarn 2>/dev/null) +NPM := $(shell command -v npm 2>/dev/null) +OGC := $(shell command -v openapi-generator-cli 2>/dev/null || command -v openapi-generator 2>/dev/null) +BROTLI := $(shell command -v brotli 2>/dev/null) +GZIP := $(shell command -v gzip 2>/dev/null) +.DEFAULT_GOAL := build + +# --- version metadata (ldflags) --- +VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") +COMMIT := $(shell git rev-parse HEAD 2>/dev/null || echo "none") +DATE := $(shell date -u +'%Y-%m-%dT%H:%M:%SZ') +BUILT_BY := $(shell whoami) + +LDFLAGS := -X '$(MODULE_PATH)/internal/version.Version=$(VERSION)' \ + -X '$(MODULE_PATH)/internal/version.Commit=$(COMMIT)' \ + -X '$(MODULE_PATH)/internal/version.Date=$(DATE)' \ + -X '$(MODULE_PATH)/internal/version.BuiltBy=$(BUILT_BY)' + +# --- phony targets --- +.PHONY: all prepare ui-install ui-build ui swagger build clean fmt vet tidy upgrade \ + sdk sdk-go sdk-ts sdk-ts-ui sdk-all worksync wire-sdk-replace help dev ui-compress \ + print-version + +# --- meta targets --- +all: build +prepare: fmt vet tidy upgrade + +# --- go hygiene --- +fmt: + @$(GOCMD) fmt ./... + +vet: + @$(GOCMD) vet ./... + +tidy: + @$(GOCMD) mod tidy + +upgrade: + @echo ">> Checking go-mod-upgrade..." + @if [ -z "$(GMU)" ]; then \ + echo "Installing go-mod-upgrade..."; \ + $(GOINSTALL) github.com/oligot/go-mod-upgrade@latest; \ + fi + @go-mod-upgrade -f || true + +# --- ui --- +ui-install: + @echo ">> Installing UI deps in $(UI_DIR)..." + @if [ -n "$(YARN)" ]; then \ + cd $(UI_DIR) && yarn install --frozen-lockfile; \ + elif [ -n "$(NPM)" ]; then \ + cd $(UI_DIR) && npm ci; \ + else \ + echo "Error: neither yarn nor npm is installed." >&2; exit 1; \ + fi + +ui-build: ui-install + @echo ">> Building UI in $(UI_DIR)..." + @rm -rf $(UI_DEST_DIR)/dist + @if [ -n "$(YARN)" ]; then \ + cd $(UI_DIR) && yarn build; \ + else \ + cd $(UI_DIR) && npm run build; \ + fi + +ui-compress: ui-build + @echo ">> Precompressing assets (brotli + gzip) in $(UI_DEST_DIR)/dist" + @if [ -n "$(BROTLI)" ]; then \ + find "$(UI_DEST_DIR)/dist" -type f \( -name '*.js' -o -name '*.css' -o -name '*.html' \) -print0 | \ + xargs -0 -I{} brotli -f {}; \ + else echo "brotli not found; skipping .br"; fi + @if [ -n "$(GZIP)" ]; then \ + find "$(UI_DEST_DIR)/dist" -type f \( -name '*.js' -o -name '*.css' -o -name '*.html' \) -print0 | \ + xargs -0 -I{} gzip -kf {}; \ + else echo "gzip not found; skipping .gz"; fi + +ui: ui-compress + +# --- swagger --- +swagger: + @echo ">> Generating Swagger docs..." + @if [ -z "$(SWAG)" ]; then \ + echo "Installing swag..."; \ + $(GOINSTALL) github.com/swaggo/swag/cmd/swag@latest; \ + fi + @rm -rf docs/swagger.* docs/docs.go + @swag init -g $(MAIN) -o docs + +# --- build --- +build: prepare ui swagger sdk-all + @echo ">> Building Go binary: $(BIN)" + @$(GOCMD) build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN) $(MAIN) + +# Handy: print resolved version metadata +print-version: + @echo "VERSION = $(VERSION)" + @echo "COMMIT = $(COMMIT)" + @echo "DATE = $(DATE)" + @echo "BUILT_BY = $(BUILT_BY)" + @echo "LDFLAGS = $(LDFLAGS)" + +# --- development --- +dev: ui-install swagger + @echo ">> Starting Vite (frontend) and Go API (backend) with dev env..." + @cd $(UI_DIR) && \ + ( \ + if command -v yarn >/dev/null 2>&1; then \ + yarn dev & \ + elif command -v npm >/dev/null 2>&1; then \ + npm run dev & \ + else \ + echo "Error: neither yarn nor npm is installed." >&2; exit 1; \ + fi; \ + cd .. && \ + $(GOCMD) run . serve & \ + wait \ + ) + +# --- sdk generation (Go) --- +sdk-go: swagger + @echo ">> Generating Go SDK (module $(GIT_HOST)/$(GIT_USER)/$(SDK_REPO), Go $(GO_VERSION))..." + @set -e; \ + export GO_POST_PROCESS_FILE="gofmt -w"; \ + if [ -z "$(OGC)" ]; then \ + if [ -z "$(NPM)" ]; then \ + echo "Error: npm is required to install openapi-generator-cli." >&2; exit 1; \ + fi; \ + echo "Installing openapi-generator-cli..."; \ + $(NPM) i -g @openapitools/openapi-generator-cli; \ + OGC_BIN=openapi-generator-cli; \ + else \ + OGC_BIN="$(OGC)"; \ + fi; \ + rm -rf "$(SDK_OUTDIR)"; \ + mkdir -p "$(SDK_OUTDIR)"; \ + "$$OGC_BIN" generate \ + --enable-post-process-file \ + --generate-alias-as-model \ + -i docs/swagger.json \ + -g go \ + -o "$(SDK_OUTDIR)" \ + --additional-properties=packageName=$(SDK_PKG) \ + --git-host "$(GIT_HOST)" \ + --git-user-id "$(GIT_USER)" \ + --git-repo-id "$(SDK_REPO)"; \ + cd "$(SDK_OUTDIR)"; \ + $(GOCMD) mod edit -go=$(GO_VERSION); \ + $(GOCMD) mod tidy + +# --- sdk generation (TypeScript) --- +sdk-ts: swagger + @set -e; \ + if [ -z "$(OGC)" ]; then \ + if [ -z "$(NPM)" ]; then echo "Error: npm is required to install openapi-generator-cli." >&2; exit 1; fi; \ + echo "Installing openapi-generator-cli..."; \ + $(NPM) i -g @openapitools/openapi-generator-cli; \ + OGC_BIN=openapi-generator-cli; \ + else \ + OGC_BIN="$(OGC)"; \ + fi; \ + rm -rf "$(SDK_TS_DIR)"; \ + mkdir -p "$(SDK_TS_DIR)"; \ + "$$OGC_BIN" generate \ + -i docs/swagger.json \ + -g "$(SDK_TS_GEN)" \ + -o "$(SDK_TS_DIR)" \ + -p npmName=$(SDK_TS_NPM_NAME) \ + -p npmVersion=$(SDK_TS_NPM_VER) \ + $(SDK_TS_PROPS_FLAGS); \ + if [ ! -d "$(SDK_TS_DIR)" ]; then \ + echo "Generation failed: $(SDK_TS_DIR) not found." >&2; exit 1; \ + fi; \ + if command -v npx >/dev/null 2>&1; then \ + echo ">> Prettier: formatting generated TS SDK"; \ + cd "$(SDK_TS_DIR)" && npx --yes prettier -w . || true; \ + fi; \ + echo ">> Installing & building TS SDK in $(SDK_TS_DIR)"; \ + if command -v yarn >/dev/null 2>&1; then \ + cd "$(SDK_TS_DIR)" && yarn install --frozen-lockfile || true; \ + cd "$(SDK_TS_DIR)" && yarn build || true; \ + elif command -v npm >/dev/null 2>&1; then \ + cd "$(SDK_TS_DIR)" && npm ci || npm install || true; \ + cd "$(SDK_TS_DIR)" && npm run build || true; \ + else \ + echo "Warning: neither yarn nor npm is installed; skipping install/build for TS SDK."; \ + fi + +# --- sdk generation (TypeScript into UI/src) --- +sdk-ts-ui: swagger + @echo ">> Generating TypeScript SDK directly into UI source: $(SDK_TS_UI_DIR)" + @set -e; \ + if [ -z "$(OGC)" ]; then \ + if [ -z "$(NPM)" ]; then \ + echo "Error: npm is required to install openapi-generator-cli." >&2; exit 1; \ + fi; \ + echo "Installing openapi-generator-cli..."; \ + $(NPM) i -g @openapitools/openapi-generator-cli; \ + OGC_BIN=openapi-generator-cli; \ + else \ + OGC_BIN="$(OGC)"; \ + fi; \ + rm -rf "$(SDK_TS_UI_DIR)"; \ + mkdir -p "$(SDK_TS_UI_DIR)"; \ + "$$OGC_BIN" generate \ + -i docs/swagger.json \ + -g typescript-fetch \ + -o "$(SDK_TS_UI_DIR)" \ + -p npmName=$(SDK_TS_NPM_NAME) \ + -p npmVersion=$(SDK_TS_NPM_VER) \ + $(SDK_TS_PROPS_FLAGS); \ + # --- move src/* up one level --- + @if [ -d "$(SDK_TS_UI_DIR)/src" ]; then \ + mv "$(SDK_TS_UI_DIR)/src/"* "$(SDK_TS_UI_DIR)/"; \ + rm -rf "$(SDK_TS_UI_DIR)/src"; \ + fi; \ + rm -f "$(SDK_TS_UI_DIR)/package.json" "$(SDK_TS_UI_DIR)/tsconfig.json" "$(SDK_TS_UI_DIR)/README.md" + +# convenience +sdk-all: sdk-go sdk-ts sdk-ts-ui +sdk: sdk-go + +# --- clean/help --- +clean: + @echo ">> Cleaning artifacts..." + @rm -rf "$(BIN)" docs/swagger.* docs/docs.go $(UI_DEST_DIR)/dist $(UI_DIR)/dist $(UI_DIR)/node_modules "$(SDK_OUTDIR)" "$(SDK_TS_OUTDIR)" + +help: + @echo "Targets:" + @echo " build - fmt, vet, tidy, upgrade, build UI, generate Swagger, build Go binary (with ldflags)" + @echo " ui - build the Vite UI and copy to $(UI_DEST_DIR)/dist (with compression)" + @echo " swagger - (re)generate Swagger docs using swag" + @echo " sdk-go (sdk) - generate Go SDK with correct module path and Go version" + @echo " sdk-ts - generate TypeScript SDK (typescript-fetch) with package.json" + @echo " sdk-ts-ui - generate TypeScript SDK directly into ui/src for inline consumption" + @echo " sdk-all - generate both Go and TypeScript SDKs" + @echo " dev - run Vite UI dev server + Go API" + @echo " clean - remove binary, Swagger outputs, UI dist, and SDKs" + @echo " prepare - fmt, vet, tidy, upgrade deps" + @echo " print-version - show computed ldflags values" diff --git a/cmd/encryption.go b/cmd/encryption.go new file mode 100644 index 0000000..2595280 --- /dev/null +++ b/cmd/encryption.go @@ -0,0 +1,83 @@ +package cmd + +import ( + "crypto/rand" + "encoding/base64" + "fmt" + "io" + + "github.com/glueops/autoglue/internal/app" + "github.com/glueops/autoglue/internal/models" + "github.com/spf13/cobra" +) + +var rotateMasterCmd = &cobra.Command{ + Use: "rotate-master", + Short: "Generate and activate a new master encryption key", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + rt := app.NewRuntime() + db := rt.DB + + key := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + return fmt.Errorf("generating random key: %w", err) + } + + encoded := base64.StdEncoding.EncodeToString(key) + + if err := db.Model(&models.MasterKey{}). + Where("is_active = ?", true). + Update("is_active", false).Error; err != nil { + return fmt.Errorf("deactivating previous key: %w", err) + } + + if err := db.Create(&models.MasterKey{ + Key: encoded, + IsActive: true, + }).Error; err != nil { + return fmt.Errorf("creating new master key: %w", err) + } + + fmt.Println("Master key rotated successfully") + return nil + }, +} + +var createMasterCmd = &cobra.Command{ + Use: "create-master", + Short: "Generate and activate a new master encryption key", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + rt := app.NewRuntime() + db := rt.DB + key := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + return fmt.Errorf("generating random key: %w", err) + } + + encoded := base64.StdEncoding.EncodeToString(key) + + if err := db.Create(&models.MasterKey{ + Key: encoded, + IsActive: true, + }).Error; err != nil { + return fmt.Errorf("creating master key: %w", err) + } + + fmt.Println("Master key created successfully") + return nil + }, +} + +var encryptCmd = &cobra.Command{ + Use: "encrypt", + Short: "Manage autoglue encryption keys", + Long: "Manage autoglue master encryption keys used for securing data.", +} + +func init() { + encryptCmd.AddCommand(rotateMasterCmd) + encryptCmd.AddCommand(createMasterCmd) + rootCmd.AddCommand(encryptCmd) +} diff --git a/cmd/keys_generate.go b/cmd/keys_generate.go new file mode 100644 index 0000000..1efbd3c --- /dev/null +++ b/cmd/keys_generate.go @@ -0,0 +1,81 @@ +package cmd + +import ( + "fmt" + "time" + + "github.com/glueops/autoglue/internal/app" + "github.com/glueops/autoglue/internal/keys" + "github.com/spf13/cobra" +) + +var ( + alg string + rsaBits int + kidFlag string + nbfStr string + expStr string +) + +var keysCmd = &cobra.Command{ + Use: "keys", + Short: "Manage JWT signing keys", +} + +var keysGenCmd = &cobra.Command{ + Use: "generate", + Short: "Generate and store a new signing key", + RunE: func(_ *cobra.Command, _ []string) error { + rt := app.NewRuntime() + + var nbfPtr, expPtr *time.Time + if nbfStr != "" { + t, err := time.Parse(time.RFC3339, nbfStr) + if err != nil { + return err + } + nbfPtr = &t + } + if expStr != "" { + t, err := time.Parse(time.RFC3339, expStr) + if err != nil { + return err + } + expPtr = &t + } + + rec, err := keys.GenerateAndStore(rt.DB, rt.Cfg.JWTPrivateEncKey, keys.GenOpts{ + Alg: alg, + Bits: rsaBits, + KID: kidFlag, + NBF: nbfPtr, + EXP: expPtr, + }) + if err != nil { + return err + } + + fmt.Printf("created signing key\n") + fmt.Printf(" kid: %s\n", rec.Kid) + fmt.Printf(" alg: %s\n", rec.Alg) + fmt.Printf(" active: %v\n", rec.IsActive) + if rec.NotBefore != nil { + fmt.Printf(" nbf: %s\n", rec.NotBefore.Format(time.RFC3339)) + } + if rec.ExpiresAt != nil { + fmt.Printf(" exp: %s\n", rec.ExpiresAt.Format(time.RFC3339)) + } + return nil + }, +} + +func init() { + rootCmd.AddCommand(keysCmd) + keysCmd.AddCommand(keysGenCmd) + + keysGenCmd.Flags().StringVarP(&alg, "alg", "a", "EdDSA", "Signing alg: EdDSA|RS256|RS384|RS512") + keysGenCmd.Flags().IntVarP(&rsaBits, "bits", "b", 3072, "RSA key size (when alg is RS*)") + keysGenCmd.Flags().StringVarP(&kidFlag, "kid", "k", "", "Key ID (optional; auto if empty)") + keysGenCmd.Flags().StringVarP(&nbfStr, "nbf", "n", "", "Not Before (RFC3339)") + keysGenCmd.Flags().StringVarP(&expStr, "exp", "e", "", "Expires At (RFC3339)") +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..ca9e7f8 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,33 @@ +package cmd + +import ( + "log" + + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "autoglue", + Short: "Autoglue Kubernetes Cluster Management", + Long: "autoglue is used to manage the lifecycle of kubernetes clusters on GlueOps supported cloud providers", + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + err := serveCmd.RunE(cmd, args) + if err != nil { + log.Fatal(err) + } + } else { + _ = cmd.Help() + } + }, +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + log.Fatal(err) + } +} + +func init() { + cobra.OnInitialize() +} diff --git a/cmd/serve.go b/cmd/serve.go new file mode 100644 index 0000000..be5ff20 --- /dev/null +++ b/cmd/serve.go @@ -0,0 +1,94 @@ +package cmd + +import ( + "context" + "errors" + "fmt" + "log" + "net/http" + "os" + "os/signal" + "strings" + "syscall" + "time" + + "github.com/glueops/autoglue/internal/api" + "github.com/glueops/autoglue/internal/app" + "github.com/glueops/autoglue/internal/auth" + "github.com/glueops/autoglue/internal/config" + "github.com/spf13/cobra" +) + +var serveCmd = &cobra.Command{ + Use: "serve", + Short: "Start API server", + RunE: func(_ *cobra.Command, _ []string) error { + rt := app.NewRuntime() + + cfg, err := config.Load() + if err != nil { + return err + } + + _ = auth.Refresh(rt.DB, rt.Cfg.JWTPrivateEncKey) + go func() { + t := time.NewTicker(60 * time.Second) + defer t.Stop() + for range t.C { + _ = auth.Refresh(rt.DB, rt.Cfg.JWTPrivateEncKey) + } + }() + + r := api.NewRouter(rt.DB) + + addr := fmt.Sprintf("%s:%s", cfg.Host, cfg.Port) + + srv := &http.Server{ + Addr: addr, + Handler: TimeoutExceptUpgrades(r, 60*time.Second, "request timed out"), // global safety + ReadTimeout: 15 * time.Second, + WriteTimeout: 60 * time.Second, + IdleTimeout: 120 * time.Second, + } + + ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) + defer stop() + + go func() { + fmt.Printf("🚀 API running on http://%s (ui.dev=%v)\n", addr, cfg.UIDev) + if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { + log.Fatalf("server error: %v", err) + } + }() + + <-ctx.Done() + fmt.Println("\n⏳ Shutting down...") + shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + return srv.Shutdown(shutdownCtx) + }, +} + +func init() { + rootCmd.AddCommand(serveCmd) +} + +func TimeoutExceptUpgrades(next http.Handler, d time.Duration, msg string) http.Handler { + timeout := http.TimeoutHandler(next, d, msg) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // If this is an upgrade (e.g., websocket), don't wrap. + if isUpgrade(r) { + next.ServeHTTP(w, r) + return + } + timeout.ServeHTTP(w, r) + }) +} + +func isUpgrade(r *http.Request) bool { + // Connection: Upgrade, Upgrade: websocket + if strings.Contains(strings.ToLower(r.Header.Get("Connection")), "upgrade") { + return true + } + return false +} diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 0000000..5573ef7 --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "fmt" + + "github.com/glueops/autoglue/internal/version" + "github.com/spf13/cobra" +) + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Show version information", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println(version.Info()) + }, +} + +func init() { + rootCmd.AddCommand(versionCmd) +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8821211 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,52 @@ +services: + autoglue: + # image: ghcr.io/glueops/autoglue:latest + build: . + ports: + - 8080:8080 + expose: + - 8080 + env_file: .env + environment: + AUTOGLUE_DATABASE_DSN: postgres://$DB_USER:$DB_PASSWORD@postgres:5432/$DB_NAME + AUTOGLUE_BIND_ADDRESS: 0.0.0.0 + depends_on: + - postgres + + postgres: + build: + context: postgres + env_file: .env + environment: + POSTGRES_USER: $DB_USER + POSTGRES_PASSWORD: $DB_PASSWORD + POSTGRES_DB: $DB_NAME + expose: + - 5432 + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + + pgweb: + image: sosedoff/pgweb@sha256:8f1ed22e10c9da0912169b98b62ddc54930dc39a5ae07b0f1354d2a93d44c6ed + restart: always + ports: + - "8081:8081" + links: + - postgres:postgres + env_file: .env + environment: + PGWEB_DATABASE_URL: postgres://$DB_USER:$DB_PASSWORD@postgres:5432/$DB_NAME + depends_on: + - postgres + + mailpit: + image: axllent/mailpit@sha256:6abc8e633df15eaf785cfcf38bae48e66f64beecdc03121e249d0f9ec15f0707 + restart: always + ports: + - "1025:1025" + - "8025:8025" + +volumes: + postgres_data: diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..c172431 --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,26 @@ +// Code generated by swaggo/swag. DO NOT EDIT. + +package docs + +import "github.com/swaggo/swag/v2" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }},"swagger":"2.0","info":{"description":"{{escape .Description}}","title":"{{.Title}}","contact":{"name":"GlueOps"},"version":"{{.Version}}"},"host":"{{.Host}}","basePath":"{{.BasePath}}","paths":{"/.well-known/jwks.json":{"get":{"description":"Returns the JSON Web Key Set for token verification","produces":["application/json"],"tags":["Auth"],"summary":"Get JWKS","operationId":"getJWKS","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.JWKS"}}}}},"/auth/logout":{"post":{"consumes":["application/json"],"produces":["application/json"],"tags":["Auth"],"summary":"Revoke refresh token family (logout everywhere)","operationId":"Logout","parameters":[{"description":"Refresh token","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.LogoutRequest"}}],"responses":{"204":{"description":"No Content"}}}},"/auth/refresh":{"post":{"consumes":["application/json"],"produces":["application/json"],"tags":["Auth"],"summary":"Rotate refresh token","operationId":"Refresh","parameters":[{"description":"Refresh token","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.RefreshRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TokenPair"}}}}},"/auth/{provider}/callback":{"get":{"produces":["application/json"],"tags":["Auth"],"summary":"Handle social login callback","operationId":"AuthCallback","parameters":[{"type":"string","description":"google|github","name":"provider","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TokenPair"}}}}},"/auth/{provider}/start":{"post":{"description":"Returns provider authorization URL for the frontend to redirect","produces":["application/json"],"tags":["Auth"],"summary":"Begin social login","operationId":"AuthStart","parameters":[{"type":"string","description":"google|github","name":"provider","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.AuthStartResponse"}}}}},"/me":{"get":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"produces":["application/json"],"tags":["Me"],"summary":"Get current user profile","operationId":"GetMe","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.meResponse"}}}},"patch":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Me"],"summary":"Update current user profile","operationId":"UpdateMe","parameters":[{"description":"Patch profile","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.updateMeRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.User"}}}}},"/me/api-keys":{"get":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"produces":["application/json"],"tags":["Me / API Keys"],"summary":"List my API keys","operationId":"ListUserAPIKeys","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/handlers.userAPIKeyOut"}}}}},"post":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"description":"Returns the plaintext key once. Store it securely on the client side.","consumes":["application/json"],"produces":["application/json"],"tags":["Me / API Keys"],"summary":"Create a new user API key","operationId":"CreateUserAPIKey","parameters":[{"description":"Key options","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.createUserKeyRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/handlers.userAPIKeyOut"}}}}},"/me/api-keys/{id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Me / API Keys"],"summary":"Delete a user API key","operationId":"DeleteUserAPIKey","parameters":[{"type":"string","description":"Key ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content"}}}},"/orgs":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List organizations I belong to","operationId":"listMyOrgs","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/models.Organization"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Create organization","operationId":"createOrg","parameters":[{"description":"Org payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgCreateReq"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/models.Organization"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"409":{"description":"Conflict","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Get organization","operationId":"getOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.Organization"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Delete organization (owner)","operationId":"deleteOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"patch":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Update organization (owner/admin)","operationId":"updateOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"Update payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgUpdateReq"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.Organization"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/api-keys":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List org-scoped API keys (no secrets)","operationId":"listOrgKeys","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/models.APIKey"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Create org key/secret pair (owner/admin)","operationId":"createOrgKey","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"Key name + optional expiry","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgKeyCreateReq"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/handlers.orgKeyCreateResp"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/api-keys/{key_id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Delete org key (owner/admin)","operationId":"deleteOrgKey","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"type":"string","description":"Key ID (UUID)","name":"key_id","in":"path","required":true}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/members":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List members in org","operationId":"listMembers","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/handlers.memberOut"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Add or update a member (owner/admin)","operationId":"addOrUpdateMember","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"User \u0026 role","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.memberUpsertReq"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.memberOut"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/members/{user_id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Remove a member (owner/admin)","operationId":"removeMember","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"type":"string","description":"User ID (UUID)","name":"user_id","in":"path","required":true}],"responses":{"204":{"description":"Removed"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/servers":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns servers for the organization in X-Org-ID. Optional filters: status, role.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"List servers (org scoped)","operationId":"ListServers","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Filter by status (pending|provisioning|ready|failed)","name":"status","in":"query"},{"type":"string","description":"Filter by role","name":"role","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.ServerResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list servers","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Create server (org scoped)","operationId":"CreateServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Server payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateServerRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid json / missing fields / invalid status / invalid ssh_key_id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/servers/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns one server in the given organization.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Get server by ID (org scoped)","operationId":"GetServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the server.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Delete server (org scoped)","operationId":"DeleteServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update fields; changing ssh_key_id validates ownership.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Update server (org scoped)","operationId":"UpdateServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateServerRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid id / invalid json / invalid status / invalid ssh_key_id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}},"/ssh":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns ssh keys for the organization in X-Org-ID.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"List ssh keys (org scoped)","operationId":"ListPublicSshKeys","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.SshResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list keys","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Create ssh keypair (org scoped)","operationId":"CreateSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Key generation options","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateSSHRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.SshResponse"}},"400":{"description":"invalid json / invalid bits","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"generation/create failed","schema":{"type":"string"}}}}},"/ssh/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns public key fields. Append ` + "`" + `?reveal=true` + "`" + ` to include the private key PEM.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Get ssh key by ID (org scoped)","operationId":"GetSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true},{"type":"boolean","description":"Reveal private key PEM","name":"reveal","in":"query"}],"responses":{"200":{"description":"When reveal=true","schema":{"$ref":"#/definitions/dto.SshRevealResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes a keypair.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Delete ssh keypair (org scoped)","operationId":"DeleteSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}}},"/ssh/{id}/download":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Download ` + "`" + `part=public|private|both` + "`" + ` of the keypair. ` + "`" + `both` + "`" + ` returns a zip file.","produces":["application/json"],"tags":["Ssh"],"summary":"Download ssh key files by ID (org scoped)","operationId":"DownloadSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header","required":true},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true},{"enum":["public","private","both"],"type":"string","description":"Which part to download","name":"part","in":"query","required":true}],"responses":{"200":{"description":"file content","schema":{"type":"string"}},"400":{"description":"invalid id / invalid part","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"download failed","schema":{"type":"string"}}}}},"/taints":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns node taints for the organization in X-Org-ID. Filters: ` + "`" + `key` + "`" + `, ` + "`" + `value` + "`" + `, and ` + "`" + `q` + "`" + ` (key contains). Add ` + "`" + `include=node_pools` + "`" + ` to include linked node pools.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"List node pool taints (org scoped)","operationId":"ListTaints","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Exact key","name":"key","in":"query"},{"type":"string","description":"Exact value","name":"value","in":"query"},{"type":"string","description":"key contains (case-insensitive)","name":"q","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.TaintResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list node taints","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a taint.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Create node taint (org scoped)","operationId":"CreateTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Taint payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateTaintRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid json / missing fields / invalid node_pool_ids","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/taints/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Get node taint by ID (org scoped)","operationId":"GetTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the taint.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Delete taint (org scoped)","operationId":"DeleteTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update taint fields.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Update node taint (org scoped)","operationId":"UpdateTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateTaintRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid id / invalid json","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}}},"definitions":{"dto.AuthStartResponse":{"type":"object","properties":{"auth_url":{"type":"string","example":"https://accounts.google.com/o/oauth2/v2/auth?client_id=..."}}},"dto.CreateSSHRequest":{"type":"object","properties":{"bits":{"description":"Only for RSA","type":"integer"},"comment":{"type":"string","example":"deploy@autoglue"},"name":{"type":"string"},"type":{"description":"\"rsa\" (default) or \"ed25519\"","type":"string"}}},"dto.CreateServerRequest":{"type":"object","properties":{"hostname":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string","example":"master|worker|bastion"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string","example":"pending|provisioning|ready|failed"}}},"dto.CreateTaintRequest":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"dto.JWK":{"type":"object","properties":{"alg":{"type":"string","example":"RS256"},"e":{"type":"string","example":"AQAB"},"kid":{"type":"string","example":"7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345"},"kty":{"type":"string","example":"RSA"},"n":{"type":"string"},"use":{"type":"string","example":"sig"},"x":{"type":"string"}}},"dto.JWKS":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/definitions/dto.JWK"}}}},"dto.LogoutRequest":{"type":"object","properties":{"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf..."}}},"dto.RefreshRequest":{"type":"object","properties":{"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf..."}}},"dto.ServerResponse":{"type":"object","properties":{"created_at":{"type":"string"},"hostname":{"type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string"},"updated_at":{"type":"string"}}},"dto.SshResponse":{"type":"object","properties":{"created_at":{"type":"string"},"fingerprint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"organization_id":{"type":"string"},"public_key":{"type":"string"},"updated_at":{"type":"string"}}},"dto.SshRevealResponse":{"type":"object","properties":{"created_at":{"type":"string"},"fingerprint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"organization_id":{"type":"string"},"private_key":{"type":"string"},"public_key":{"type":"string"},"updated_at":{"type":"string"}}},"dto.TaintResponse":{"type":"object","properties":{"effect":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"dto.TokenPair":{"type":"object","properties":{"access_token":{"type":"string","example":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij..."},"expires_in":{"type":"integer","example":3600},"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf...."},"token_type":{"type":"string","example":"Bearer"}}},"dto.UpdateServerRequest":{"type":"object","properties":{"hostname":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string","example":"master|worker|bastion"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string","example":"pending|provisioning|ready|failed"}}},"dto.UpdateTaintRequest":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"handlers.createUserKeyRequest":{"type":"object","properties":{"expires_in_hours":{"description":"optional TTL","type":"integer"},"name":{"type":"string"}}},"handlers.meResponse":{"type":"object","properties":{"avatar_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"display_name":{"type":"string"},"emails":{"type":"array","items":{"$ref":"#/definitions/models.UserEmail"}},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_disabled":{"type":"boolean"},"organizations":{"type":"array","items":{"$ref":"#/definitions/models.Organization"}},"primary_email":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"handlers.memberOut":{"type":"object","properties":{"email":{"type":"string"},"role":{"description":"owner/admin/member","type":"string"},"user_id":{"type":"string","format":"uuid"}}},"handlers.memberUpsertReq":{"type":"object","properties":{"role":{"type":"string","example":"member"},"user_id":{"type":"string","format":"uuid"}}},"handlers.orgCreateReq":{"type":"object","properties":{"domain":{"type":"string","example":"acme.com"},"name":{"type":"string","example":"Acme Corp"}}},"handlers.orgKeyCreateReq":{"type":"object","properties":{"expires_in_hours":{"type":"integer","example":720},"name":{"type":"string","example":"automation-bot"}}},"handlers.orgKeyCreateResp":{"type":"object","properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"org_key":{"description":"shown once:","type":"string"},"org_secret":{"description":"shown once:","type":"string"},"scope":{"description":"\"org\"","type":"string"}}},"handlers.orgUpdateReq":{"type":"object","properties":{"domain":{"type":"string"},"name":{"type":"string"}}},"handlers.updateMeRequest":{"type":"object","properties":{"display_name":{"type":"string"}}},"handlers.userAPIKeyOut":{"type":"object","properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":"string"},"name":{"type":"string"},"plain":{"description":"Shown only on create:","type":"string"},"scope":{"description":"\"user\"","type":"string"}}},"models.APIKey":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":"string","format":"date-time"},"name":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"prefix":{"type":"string"},"revoked":{"type":"boolean"},"scope":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"user_id":{"type":"string","format":"uuid"}}},"models.Organization":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"domain":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"name":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"models.User":{"type":"object","properties":{"avatar_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"display_name":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_disabled":{"type":"boolean"},"primary_email":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"models.UserEmail":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"email":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_primary":{"type":"boolean"},"is_verified":{"type":"boolean"},"updated_at":{"type":"string","format":"date-time"},"user":{"$ref":"#/definitions/models.User"},"user_id":{"type":"string","format":"uuid"}}},"utils.ErrorResponse":{"type":"object","properties":{"code":{"description":"A machine-readable error code, e.g. \"validation_error\"\nexample: validation_error","type":"string"},"message":{"description":"Human-readable message\nexample: slug is required","type":"string"}}}},"securityDefinitions":{"ApiKeyAuth":{"description":"User API key","type":"apiKey","name":"X-API-KEY","in":"header"},"BearerAuth":{"description":"Bearer token authentication","type":"apiKey","name":"Authorization","in":"header"},"OrgKeyAuth":{"description":"Org-level key/secret authentication","type":"apiKey","name":"X-ORG-KEY","in":"header"},"OrgSecretAuth":{"description":"Org-level secret","type":"apiKey","name":"X-ORG-SECRET","in":"header"}}}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "localhost:8080", + BasePath: "/api/v1", + Schemes: []string{"http", "https"}, + Title: "AutoGlue API", + Description: "API for managing K3s clusters across cloud providers", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/efs.go b/docs/efs.go new file mode 100644 index 0000000..1de7ee1 --- /dev/null +++ b/docs/efs.go @@ -0,0 +1,9 @@ +package docs + +import _ "embed" + +//go:embed swagger.json +var SwaggerJSON []byte + +//go:embed swagger.yaml +var SwaggerYAML []byte diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..175b5af --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1 @@ +{"schemes":["http","https"],"swagger":"2.0","info":{"description":"API for managing K3s clusters across cloud providers","title":"AutoGlue API","contact":{"name":"GlueOps"},"version":"1.0"},"host":"localhost:8080","basePath":"/api/v1","paths":{"/.well-known/jwks.json":{"get":{"description":"Returns the JSON Web Key Set for token verification","produces":["application/json"],"tags":["Auth"],"summary":"Get JWKS","operationId":"getJWKS","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.JWKS"}}}}},"/auth/logout":{"post":{"consumes":["application/json"],"produces":["application/json"],"tags":["Auth"],"summary":"Revoke refresh token family (logout everywhere)","operationId":"Logout","parameters":[{"description":"Refresh token","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.LogoutRequest"}}],"responses":{"204":{"description":"No Content"}}}},"/auth/refresh":{"post":{"consumes":["application/json"],"produces":["application/json"],"tags":["Auth"],"summary":"Rotate refresh token","operationId":"Refresh","parameters":[{"description":"Refresh token","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.RefreshRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TokenPair"}}}}},"/auth/{provider}/callback":{"get":{"produces":["application/json"],"tags":["Auth"],"summary":"Handle social login callback","operationId":"AuthCallback","parameters":[{"type":"string","description":"google|github","name":"provider","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TokenPair"}}}}},"/auth/{provider}/start":{"post":{"description":"Returns provider authorization URL for the frontend to redirect","produces":["application/json"],"tags":["Auth"],"summary":"Begin social login","operationId":"AuthStart","parameters":[{"type":"string","description":"google|github","name":"provider","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.AuthStartResponse"}}}}},"/me":{"get":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"produces":["application/json"],"tags":["Me"],"summary":"Get current user profile","operationId":"GetMe","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.meResponse"}}}},"patch":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Me"],"summary":"Update current user profile","operationId":"UpdateMe","parameters":[{"description":"Patch profile","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.updateMeRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.User"}}}}},"/me/api-keys":{"get":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"produces":["application/json"],"tags":["Me / API Keys"],"summary":"List my API keys","operationId":"ListUserAPIKeys","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/handlers.userAPIKeyOut"}}}}},"post":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"description":"Returns the plaintext key once. Store it securely on the client side.","consumes":["application/json"],"produces":["application/json"],"tags":["Me / API Keys"],"summary":"Create a new user API key","operationId":"CreateUserAPIKey","parameters":[{"description":"Key options","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.createUserKeyRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/handlers.userAPIKeyOut"}}}}},"/me/api-keys/{id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Me / API Keys"],"summary":"Delete a user API key","operationId":"DeleteUserAPIKey","parameters":[{"type":"string","description":"Key ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content"}}}},"/orgs":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List organizations I belong to","operationId":"listMyOrgs","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/models.Organization"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Create organization","operationId":"createOrg","parameters":[{"description":"Org payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgCreateReq"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/models.Organization"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"409":{"description":"Conflict","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Get organization","operationId":"getOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.Organization"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Delete organization (owner)","operationId":"deleteOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"patch":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Update organization (owner/admin)","operationId":"updateOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"Update payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgUpdateReq"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.Organization"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/api-keys":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List org-scoped API keys (no secrets)","operationId":"listOrgKeys","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/models.APIKey"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Create org key/secret pair (owner/admin)","operationId":"createOrgKey","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"Key name + optional expiry","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgKeyCreateReq"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/handlers.orgKeyCreateResp"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/api-keys/{key_id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Delete org key (owner/admin)","operationId":"deleteOrgKey","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"type":"string","description":"Key ID (UUID)","name":"key_id","in":"path","required":true}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/members":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List members in org","operationId":"listMembers","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/handlers.memberOut"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Add or update a member (owner/admin)","operationId":"addOrUpdateMember","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"User \u0026 role","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.memberUpsertReq"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.memberOut"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/members/{user_id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Remove a member (owner/admin)","operationId":"removeMember","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"type":"string","description":"User ID (UUID)","name":"user_id","in":"path","required":true}],"responses":{"204":{"description":"Removed"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/servers":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns servers for the organization in X-Org-ID. Optional filters: status, role.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"List servers (org scoped)","operationId":"ListServers","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Filter by status (pending|provisioning|ready|failed)","name":"status","in":"query"},{"type":"string","description":"Filter by role","name":"role","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.ServerResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list servers","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Create server (org scoped)","operationId":"CreateServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Server payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateServerRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid json / missing fields / invalid status / invalid ssh_key_id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/servers/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns one server in the given organization.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Get server by ID (org scoped)","operationId":"GetServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the server.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Delete server (org scoped)","operationId":"DeleteServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update fields; changing ssh_key_id validates ownership.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Update server (org scoped)","operationId":"UpdateServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateServerRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid id / invalid json / invalid status / invalid ssh_key_id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}},"/ssh":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns ssh keys for the organization in X-Org-ID.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"List ssh keys (org scoped)","operationId":"ListPublicSshKeys","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.SshResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list keys","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Create ssh keypair (org scoped)","operationId":"CreateSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Key generation options","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateSSHRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.SshResponse"}},"400":{"description":"invalid json / invalid bits","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"generation/create failed","schema":{"type":"string"}}}}},"/ssh/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns public key fields. Append `?reveal=true` to include the private key PEM.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Get ssh key by ID (org scoped)","operationId":"GetSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true},{"type":"boolean","description":"Reveal private key PEM","name":"reveal","in":"query"}],"responses":{"200":{"description":"When reveal=true","schema":{"$ref":"#/definitions/dto.SshRevealResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes a keypair.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Delete ssh keypair (org scoped)","operationId":"DeleteSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}}},"/ssh/{id}/download":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Download `part=public|private|both` of the keypair. `both` returns a zip file.","produces":["application/json"],"tags":["Ssh"],"summary":"Download ssh key files by ID (org scoped)","operationId":"DownloadSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header","required":true},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true},{"enum":["public","private","both"],"type":"string","description":"Which part to download","name":"part","in":"query","required":true}],"responses":{"200":{"description":"file content","schema":{"type":"string"}},"400":{"description":"invalid id / invalid part","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"download failed","schema":{"type":"string"}}}}},"/taints":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns node taints for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"List node pool taints (org scoped)","operationId":"ListTaints","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Exact key","name":"key","in":"query"},{"type":"string","description":"Exact value","name":"value","in":"query"},{"type":"string","description":"key contains (case-insensitive)","name":"q","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.TaintResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list node taints","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a taint.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Create node taint (org scoped)","operationId":"CreateTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Taint payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateTaintRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid json / missing fields / invalid node_pool_ids","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/taints/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Get node taint by ID (org scoped)","operationId":"GetTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the taint.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Delete taint (org scoped)","operationId":"DeleteTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update taint fields.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Update node taint (org scoped)","operationId":"UpdateTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateTaintRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid id / invalid json","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}}},"definitions":{"dto.AuthStartResponse":{"type":"object","properties":{"auth_url":{"type":"string","example":"https://accounts.google.com/o/oauth2/v2/auth?client_id=..."}}},"dto.CreateSSHRequest":{"type":"object","properties":{"bits":{"description":"Only for RSA","type":"integer"},"comment":{"type":"string","example":"deploy@autoglue"},"name":{"type":"string"},"type":{"description":"\"rsa\" (default) or \"ed25519\"","type":"string"}}},"dto.CreateServerRequest":{"type":"object","properties":{"hostname":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string","example":"master|worker|bastion"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string","example":"pending|provisioning|ready|failed"}}},"dto.CreateTaintRequest":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"dto.JWK":{"type":"object","properties":{"alg":{"type":"string","example":"RS256"},"e":{"type":"string","example":"AQAB"},"kid":{"type":"string","example":"7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345"},"kty":{"type":"string","example":"RSA"},"n":{"type":"string"},"use":{"type":"string","example":"sig"},"x":{"type":"string"}}},"dto.JWKS":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/definitions/dto.JWK"}}}},"dto.LogoutRequest":{"type":"object","properties":{"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf..."}}},"dto.RefreshRequest":{"type":"object","properties":{"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf..."}}},"dto.ServerResponse":{"type":"object","properties":{"created_at":{"type":"string"},"hostname":{"type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string"},"updated_at":{"type":"string"}}},"dto.SshResponse":{"type":"object","properties":{"created_at":{"type":"string"},"fingerprint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"organization_id":{"type":"string"},"public_key":{"type":"string"},"updated_at":{"type":"string"}}},"dto.SshRevealResponse":{"type":"object","properties":{"created_at":{"type":"string"},"fingerprint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"organization_id":{"type":"string"},"private_key":{"type":"string"},"public_key":{"type":"string"},"updated_at":{"type":"string"}}},"dto.TaintResponse":{"type":"object","properties":{"effect":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"dto.TokenPair":{"type":"object","properties":{"access_token":{"type":"string","example":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij..."},"expires_in":{"type":"integer","example":3600},"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf...."},"token_type":{"type":"string","example":"Bearer"}}},"dto.UpdateServerRequest":{"type":"object","properties":{"hostname":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string","example":"master|worker|bastion"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string","example":"pending|provisioning|ready|failed"}}},"dto.UpdateTaintRequest":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"handlers.createUserKeyRequest":{"type":"object","properties":{"expires_in_hours":{"description":"optional TTL","type":"integer"},"name":{"type":"string"}}},"handlers.meResponse":{"type":"object","properties":{"avatar_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"display_name":{"type":"string"},"emails":{"type":"array","items":{"$ref":"#/definitions/models.UserEmail"}},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_disabled":{"type":"boolean"},"organizations":{"type":"array","items":{"$ref":"#/definitions/models.Organization"}},"primary_email":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"handlers.memberOut":{"type":"object","properties":{"email":{"type":"string"},"role":{"description":"owner/admin/member","type":"string"},"user_id":{"type":"string","format":"uuid"}}},"handlers.memberUpsertReq":{"type":"object","properties":{"role":{"type":"string","example":"member"},"user_id":{"type":"string","format":"uuid"}}},"handlers.orgCreateReq":{"type":"object","properties":{"domain":{"type":"string","example":"acme.com"},"name":{"type":"string","example":"Acme Corp"}}},"handlers.orgKeyCreateReq":{"type":"object","properties":{"expires_in_hours":{"type":"integer","example":720},"name":{"type":"string","example":"automation-bot"}}},"handlers.orgKeyCreateResp":{"type":"object","properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"org_key":{"description":"shown once:","type":"string"},"org_secret":{"description":"shown once:","type":"string"},"scope":{"description":"\"org\"","type":"string"}}},"handlers.orgUpdateReq":{"type":"object","properties":{"domain":{"type":"string"},"name":{"type":"string"}}},"handlers.updateMeRequest":{"type":"object","properties":{"display_name":{"type":"string"}}},"handlers.userAPIKeyOut":{"type":"object","properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":"string"},"name":{"type":"string"},"plain":{"description":"Shown only on create:","type":"string"},"scope":{"description":"\"user\"","type":"string"}}},"models.APIKey":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":"string","format":"date-time"},"name":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"prefix":{"type":"string"},"revoked":{"type":"boolean"},"scope":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"user_id":{"type":"string","format":"uuid"}}},"models.Organization":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"domain":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"name":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"models.User":{"type":"object","properties":{"avatar_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"display_name":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_disabled":{"type":"boolean"},"primary_email":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"models.UserEmail":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"email":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_primary":{"type":"boolean"},"is_verified":{"type":"boolean"},"updated_at":{"type":"string","format":"date-time"},"user":{"$ref":"#/definitions/models.User"},"user_id":{"type":"string","format":"uuid"}}},"utils.ErrorResponse":{"type":"object","properties":{"code":{"description":"A machine-readable error code, e.g. \"validation_error\"\nexample: validation_error","type":"string"},"message":{"description":"Human-readable message\nexample: slug is required","type":"string"}}}},"securityDefinitions":{"ApiKeyAuth":{"description":"User API key","type":"apiKey","name":"X-API-KEY","in":"header"},"BearerAuth":{"description":"Bearer token authentication","type":"apiKey","name":"Authorization","in":"header"},"OrgKeyAuth":{"description":"Org-level key/secret authentication","type":"apiKey","name":"X-ORG-KEY","in":"header"},"OrgSecretAuth":{"description":"Org-level secret","type":"apiKey","name":"X-ORG-SECRET","in":"header"}}} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..ef51348 --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,1731 @@ +basePath: /api/v1 +definitions: + dto.AuthStartResponse: + properties: + auth_url: + example: https://accounts.google.com/o/oauth2/v2/auth?client_id=... + type: string + type: object + dto.CreateSSHRequest: + properties: + bits: + description: Only for RSA + type: integer + comment: + example: deploy@autoglue + type: string + name: + type: string + type: + description: '"rsa" (default) or "ed25519"' + type: string + type: object + dto.CreateServerRequest: + properties: + hostname: + type: string + private_ip_address: + type: string + public_ip_address: + type: string + role: + example: master|worker|bastion + type: string + ssh_key_id: + type: string + ssh_user: + type: string + status: + example: pending|provisioning|ready|failed + type: string + type: object + dto.CreateTaintRequest: + properties: + effect: + type: string + key: + type: string + value: + type: string + type: object + dto.JWK: + properties: + alg: + example: RS256 + type: string + e: + example: AQAB + type: string + kid: + example: 7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345 + type: string + kty: + example: RSA + type: string + "n": + type: string + use: + example: sig + type: string + x: + type: string + type: object + dto.JWKS: + properties: + keys: + items: + $ref: '#/definitions/dto.JWK' + type: array + type: object + dto.LogoutRequest: + properties: + refresh_token: + example: m0l9o8rT3t0V8d3eFf... + type: string + type: object + dto.RefreshRequest: + properties: + refresh_token: + example: m0l9o8rT3t0V8d3eFf... + type: string + type: object + dto.ServerResponse: + properties: + created_at: + type: string + hostname: + type: string + id: + type: string + organization_id: + type: string + private_ip_address: + type: string + public_ip_address: + type: string + role: + type: string + ssh_key_id: + type: string + ssh_user: + type: string + status: + type: string + updated_at: + type: string + type: object + dto.SshResponse: + properties: + created_at: + type: string + fingerprint: + type: string + id: + type: string + name: + type: string + organization_id: + type: string + public_key: + type: string + updated_at: + type: string + type: object + dto.SshRevealResponse: + properties: + created_at: + type: string + fingerprint: + type: string + id: + type: string + name: + type: string + organization_id: + type: string + private_key: + type: string + public_key: + type: string + updated_at: + type: string + type: object + dto.TaintResponse: + properties: + effect: + type: string + id: + type: string + key: + type: string + value: + type: string + type: object + dto.TokenPair: + properties: + access_token: + example: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij... + type: string + expires_in: + example: 3600 + type: integer + refresh_token: + example: m0l9o8rT3t0V8d3eFf.... + type: string + token_type: + example: Bearer + type: string + type: object + dto.UpdateServerRequest: + properties: + hostname: + type: string + private_ip_address: + type: string + public_ip_address: + type: string + role: + example: master|worker|bastion + type: string + ssh_key_id: + type: string + ssh_user: + type: string + status: + example: pending|provisioning|ready|failed + type: string + type: object + dto.UpdateTaintRequest: + properties: + effect: + type: string + key: + type: string + value: + type: string + type: object + handlers.createUserKeyRequest: + properties: + expires_in_hours: + description: optional TTL + type: integer + name: + type: string + type: object + handlers.meResponse: + properties: + avatar_url: + type: string + created_at: + format: date-time + type: string + display_name: + type: string + emails: + items: + $ref: '#/definitions/models.UserEmail' + type: array + id: + description: 'example: 3fa85f64-5717-4562-b3fc-2c963f66afa6' + format: uuid + type: string + is_disabled: + type: boolean + organizations: + items: + $ref: '#/definitions/models.Organization' + type: array + primary_email: + type: string + updated_at: + format: date-time + type: string + type: object + handlers.memberOut: + properties: + email: + type: string + role: + description: owner/admin/member + type: string + user_id: + format: uuid + type: string + type: object + handlers.memberUpsertReq: + properties: + role: + example: member + type: string + user_id: + format: uuid + type: string + type: object + handlers.orgCreateReq: + properties: + domain: + example: acme.com + type: string + name: + example: Acme Corp + type: string + type: object + handlers.orgKeyCreateReq: + properties: + expires_in_hours: + example: 720 + type: integer + name: + example: automation-bot + type: string + type: object + handlers.orgKeyCreateResp: + properties: + created_at: + type: string + expires_at: + type: string + id: + type: string + name: + type: string + org_key: + description: 'shown once:' + type: string + org_secret: + description: 'shown once:' + type: string + scope: + description: '"org"' + type: string + type: object + handlers.orgUpdateReq: + properties: + domain: + type: string + name: + type: string + type: object + handlers.updateMeRequest: + properties: + display_name: + type: string + type: object + handlers.userAPIKeyOut: + properties: + created_at: + type: string + expires_at: + type: string + id: + format: uuid + type: string + last_used_at: + type: string + name: + type: string + plain: + description: 'Shown only on create:' + type: string + scope: + description: '"user"' + type: string + type: object + models.APIKey: + properties: + created_at: + format: date-time + type: string + expires_at: + format: date-time + type: string + id: + format: uuid + type: string + last_used_at: + format: date-time + type: string + name: + type: string + org_id: + format: uuid + type: string + prefix: + type: string + revoked: + type: boolean + scope: + type: string + updated_at: + format: date-time + type: string + user_id: + format: uuid + type: string + type: object + models.Organization: + properties: + created_at: + format: date-time + type: string + domain: + type: string + id: + description: 'example: 3fa85f64-5717-4562-b3fc-2c963f66afa6' + format: uuid + type: string + name: + type: string + updated_at: + format: date-time + type: string + type: object + models.User: + properties: + avatar_url: + type: string + created_at: + format: date-time + type: string + display_name: + type: string + id: + description: 'example: 3fa85f64-5717-4562-b3fc-2c963f66afa6' + format: uuid + type: string + is_disabled: + type: boolean + primary_email: + type: string + updated_at: + format: date-time + type: string + type: object + models.UserEmail: + properties: + created_at: + format: date-time + type: string + email: + type: string + id: + description: 'example: 3fa85f64-5717-4562-b3fc-2c963f66afa6' + format: uuid + type: string + is_primary: + type: boolean + is_verified: + type: boolean + updated_at: + format: date-time + type: string + user: + $ref: '#/definitions/models.User' + user_id: + format: uuid + type: string + type: object + utils.ErrorResponse: + properties: + code: + description: |- + A machine-readable error code, e.g. "validation_error" + example: validation_error + type: string + message: + description: |- + Human-readable message + example: slug is required + type: string + type: object +host: localhost:8080 +info: + contact: + name: GlueOps + description: API for managing K3s clusters across cloud providers + title: AutoGlue API + version: "1.0" +paths: + /.well-known/jwks.json: + get: + description: Returns the JSON Web Key Set for token verification + operationId: getJWKS + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.JWKS' + summary: Get JWKS + tags: + - Auth + /auth/{provider}/callback: + get: + operationId: AuthCallback + parameters: + - description: google|github + in: path + name: provider + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.TokenPair' + summary: Handle social login callback + tags: + - Auth + /auth/{provider}/start: + post: + description: Returns provider authorization URL for the frontend to redirect + operationId: AuthStart + parameters: + - description: google|github + in: path + name: provider + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.AuthStartResponse' + summary: Begin social login + tags: + - Auth + /auth/logout: + post: + consumes: + - application/json + operationId: Logout + parameters: + - description: Refresh token + in: body + name: body + required: true + schema: + $ref: '#/definitions/dto.LogoutRequest' + produces: + - application/json + responses: + "204": + description: No Content + summary: Revoke refresh token family (logout everywhere) + tags: + - Auth + /auth/refresh: + post: + consumes: + - application/json + operationId: Refresh + parameters: + - description: Refresh token + in: body + name: body + required: true + schema: + $ref: '#/definitions/dto.RefreshRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.TokenPair' + summary: Rotate refresh token + tags: + - Auth + /me: + get: + operationId: GetMe + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.meResponse' + security: + - BearerAuth: [] + - ApiKeyAuth: [] + summary: Get current user profile + tags: + - Me + patch: + consumes: + - application/json + operationId: UpdateMe + parameters: + - description: Patch profile + in: body + name: body + required: true + schema: + $ref: '#/definitions/handlers.updateMeRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + security: + - BearerAuth: [] + - ApiKeyAuth: [] + summary: Update current user profile + tags: + - Me + /me/api-keys: + get: + operationId: ListUserAPIKeys + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/handlers.userAPIKeyOut' + type: array + security: + - BearerAuth: [] + - ApiKeyAuth: [] + summary: List my API keys + tags: + - Me / API Keys + post: + consumes: + - application/json + description: Returns the plaintext key once. Store it securely on the client + side. + operationId: CreateUserAPIKey + parameters: + - description: Key options + in: body + name: body + required: true + schema: + $ref: '#/definitions/handlers.createUserKeyRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/handlers.userAPIKeyOut' + security: + - BearerAuth: [] + - ApiKeyAuth: [] + summary: Create a new user API key + tags: + - Me / API Keys + /me/api-keys/{id}: + delete: + operationId: DeleteUserAPIKey + parameters: + - description: Key ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "204": + description: No Content + security: + - BearerAuth: [] + summary: Delete a user API key + tags: + - Me / API Keys + /orgs: + get: + operationId: listMyOrgs + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.Organization' + type: array + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: List organizations I belong to + tags: + - Orgs + post: + consumes: + - application/json + operationId: createOrg + parameters: + - description: Org payload + in: body + name: body + required: true + schema: + $ref: '#/definitions/handlers.orgCreateReq' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/models.Organization' + "400": + description: Bad Request + schema: + $ref: '#/definitions/utils.ErrorResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + "409": + description: Conflict + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: Create organization + tags: + - Orgs + /orgs/{id}: + delete: + operationId: deleteOrg + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "204": + description: Deleted + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + "404": + description: Not Found + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: Delete organization (owner) + tags: + - Orgs + get: + operationId: getOrg + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Organization' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + "404": + description: Not Found + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: Get organization + tags: + - Orgs + patch: + consumes: + - application/json + operationId: updateOrg + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + - description: Update payload + in: body + name: body + required: true + schema: + $ref: '#/definitions/handlers.orgUpdateReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Organization' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + "404": + description: Not Found + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: Update organization (owner/admin) + tags: + - Orgs + /orgs/{id}/api-keys: + get: + operationId: listOrgKeys + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.APIKey' + type: array + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: List org-scoped API keys (no secrets) + tags: + - Orgs + post: + consumes: + - application/json + operationId: createOrgKey + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + - description: Key name + optional expiry + in: body + name: body + required: true + schema: + $ref: '#/definitions/handlers.orgKeyCreateReq' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/handlers.orgKeyCreateResp' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: Create org key/secret pair (owner/admin) + tags: + - Orgs + /orgs/{id}/api-keys/{key_id}: + delete: + operationId: deleteOrgKey + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + - description: Key ID (UUID) + in: path + name: key_id + required: true + type: string + produces: + - application/json + responses: + "204": + description: Deleted + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: Delete org key (owner/admin) + tags: + - Orgs + /orgs/{id}/members: + get: + operationId: listMembers + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/handlers.memberOut' + type: array + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: List members in org + tags: + - Orgs + post: + consumes: + - application/json + operationId: addOrUpdateMember + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + - description: User & role + in: body + name: body + required: true + schema: + $ref: '#/definitions/handlers.memberUpsertReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.memberOut' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: Add or update a member (owner/admin) + tags: + - Orgs + /orgs/{id}/members/{user_id}: + delete: + operationId: removeMember + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + type: string + - description: User ID (UUID) + in: path + name: user_id + required: true + type: string + produces: + - application/json + responses: + "204": + description: Removed + "401": + description: Unauthorized + schema: + $ref: '#/definitions/utils.ErrorResponse' + security: + - BearerAuth: [] + summary: Remove a member (owner/admin) + tags: + - Orgs + /servers: + get: + consumes: + - application/json + description: 'Returns servers for the organization in X-Org-ID. Optional filters: + status, role.' + operationId: ListServers + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Filter by status (pending|provisioning|ready|failed) + in: query + name: status + type: string + - description: Filter by role + in: query + name: role + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/dto.ServerResponse' + type: array + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: failed to list servers + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: List servers (org scoped) + tags: + - Servers + post: + consumes: + - application/json + description: Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id + belongs to the org. + operationId: CreateServer + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Server payload + in: body + name: body + required: true + schema: + $ref: '#/definitions/dto.CreateServerRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/dto.ServerResponse' + "400": + description: invalid json / missing fields / invalid status / invalid ssh_key_id + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: create failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Create server (org scoped) + tags: + - Servers + /servers/{id}: + delete: + consumes: + - application/json + description: Permanently deletes the server. + operationId: DeleteServer + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Server ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "204": + description: No Content + schema: + type: string + "400": + description: invalid id + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: delete failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Delete server (org scoped) + tags: + - Servers + get: + consumes: + - application/json + description: Returns one server in the given organization. + operationId: GetServer + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Server ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.ServerResponse' + "400": + description: invalid id + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "404": + description: not found + schema: + type: string + "500": + description: fetch failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Get server by ID (org scoped) + tags: + - Servers + patch: + consumes: + - application/json + description: Partially update fields; changing ssh_key_id validates ownership. + operationId: UpdateServer + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Server ID (UUID) + in: path + name: id + required: true + type: string + - description: Fields to update + in: body + name: body + required: true + schema: + $ref: '#/definitions/dto.UpdateServerRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.ServerResponse' + "400": + description: invalid id / invalid json / invalid status / invalid ssh_key_id + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "404": + description: not found + schema: + type: string + "500": + description: update failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Update server (org scoped) + tags: + - Servers + /ssh: + get: + consumes: + - application/json + description: Returns ssh keys for the organization in X-Org-ID. + operationId: ListPublicSshKeys + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/dto.SshResponse' + type: array + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: failed to list keys + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: List ssh keys (org scoped) + tags: + - Ssh + post: + consumes: + - application/json + description: Generates an RSA or ED25519 keypair, saves it, and returns metadata. + For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores + bits. + operationId: CreateSSHKey + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Key generation options + in: body + name: body + required: true + schema: + $ref: '#/definitions/dto.CreateSSHRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/dto.SshResponse' + "400": + description: invalid json / invalid bits + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: generation/create failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Create ssh keypair (org scoped) + tags: + - Ssh + /ssh/{id}: + delete: + consumes: + - application/json + description: Permanently deletes a keypair. + operationId: DeleteSSHKey + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: SSH Key ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "204": + description: No Content + schema: + type: string + "400": + description: invalid id + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: delete failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Delete ssh keypair (org scoped) + tags: + - Ssh + get: + consumes: + - application/json + description: Returns public key fields. Append `?reveal=true` to include the + private key PEM. + operationId: GetSSHKey + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: SSH Key ID (UUID) + in: path + name: id + required: true + type: string + - description: Reveal private key PEM + in: query + name: reveal + type: boolean + produces: + - application/json + responses: + "200": + description: When reveal=true + schema: + $ref: '#/definitions/dto.SshRevealResponse' + "400": + description: invalid id + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "404": + description: not found + schema: + type: string + "500": + description: fetch failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Get ssh key by ID (org scoped) + tags: + - Ssh + /ssh/{id}/download: + get: + description: Download `part=public|private|both` of the keypair. `both` returns + a zip file. + operationId: DownloadSSHKey + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + required: true + type: string + - description: SSH Key ID (UUID) + in: path + name: id + required: true + type: string + - description: Which part to download + enum: + - public + - private + - both + in: query + name: part + required: true + type: string + produces: + - application/json + responses: + "200": + description: file content + schema: + type: string + "400": + description: invalid id / invalid part + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "404": + description: not found + schema: + type: string + "500": + description: download failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Download ssh key files by ID (org scoped) + tags: + - Ssh + /taints: + get: + consumes: + - application/json + description: 'Returns node taints for the organization in X-Org-ID. Filters: + `key`, `value`, and `q` (key contains). Add `include=node_pools` to include + linked node pools.' + operationId: ListTaints + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Exact key + in: query + name: key + type: string + - description: Exact value + in: query + name: value + type: string + - description: key contains (case-insensitive) + in: query + name: q + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/dto.TaintResponse' + type: array + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: failed to list node taints + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: List node pool taints (org scoped) + tags: + - Taints + post: + consumes: + - application/json + description: Creates a taint. + operationId: CreateTaint + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Taint payload + in: body + name: body + required: true + schema: + $ref: '#/definitions/dto.CreateTaintRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/dto.TaintResponse' + "400": + description: invalid json / missing fields / invalid node_pool_ids + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: create failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Create node taint (org scoped) + tags: + - Taints + /taints/{id}: + delete: + consumes: + - application/json + description: Permanently deletes the taint. + operationId: DeleteTaint + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Node Taint ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "204": + description: No Content + schema: + type: string + "400": + description: invalid id + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "500": + description: delete failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Delete taint (org scoped) + tags: + - Taints + get: + consumes: + - application/json + operationId: GetTaint + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Node Taint ID (UUID) + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.TaintResponse' + "400": + description: invalid id + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "404": + description: not found + schema: + type: string + "500": + description: fetch failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Get node taint by ID (org scoped) + tags: + - Taints + patch: + consumes: + - application/json + description: Partially update taint fields. + operationId: UpdateTaint + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + type: string + - description: Node Taint ID (UUID) + in: path + name: id + required: true + type: string + - description: Fields to update + in: body + name: body + required: true + schema: + $ref: '#/definitions/dto.UpdateTaintRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.TaintResponse' + "400": + description: invalid id / invalid json + schema: + type: string + "401": + description: Unauthorized + schema: + type: string + "403": + description: organization required + schema: + type: string + "404": + description: not found + schema: + type: string + "500": + description: update failed + schema: + type: string + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Update node taint (org scoped) + tags: + - Taints +schemes: +- http +- https +securityDefinitions: + ApiKeyAuth: + description: User API key + in: header + name: X-API-KEY + type: apiKey + BearerAuth: + description: Bearer token authentication + in: header + name: Authorization + type: apiKey + OrgKeyAuth: + description: Org-level key/secret authentication + in: header + name: X-ORG-KEY + type: apiKey + OrgSecretAuth: + description: Org-level secret + in: header + name: X-ORG-SECRET + type: apiKey +swagger: "2.0" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..39b1311 --- /dev/null +++ b/go.mod @@ -0,0 +1,70 @@ +module github.com/glueops/autoglue + +go 1.25.3 + +require ( + github.com/alexedwards/argon2id v1.0.0 + github.com/coreos/go-oidc/v3 v3.16.0 + github.com/go-chi/chi/v5 v5.2.3 + github.com/go-chi/cors v1.2.2 + github.com/go-chi/httprate v0.15.0 + github.com/golang-jwt/jwt/v5 v5.3.0 + github.com/google/uuid v1.6.0 + github.com/joho/godotenv v1.5.1 + github.com/rs/zerolog v1.34.0 + github.com/spf13/cobra v1.10.1 + github.com/spf13/viper v1.21.0 + github.com/swaggo/http-swagger/v2 v2.0.2 + github.com/swaggo/swag/v2 v2.0.0-rc4 + golang.org/x/crypto v0.35.0 + golang.org/x/oauth2 v0.32.0 + gopkg.in/yaml.v3 v3.0.1 + gorm.io/datatypes v1.2.7 + gorm.io/driver/postgres v1.6.0 + gorm.io/gorm v1.31.0 +) + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-jose/go-jose/v4 v4.1.3 // indirect + github.com/go-openapi/jsonpointer v0.22.1 // indirect + github.com/go-openapi/jsonreference v0.21.2 // indirect + github.com/go-openapi/spec v0.20.9 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgx/v5 v5.6.0 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/sagikazarmark/locafero v0.11.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/sv-tools/openapi v0.2.1 // indirect + github.com/swaggo/files/v2 v2.0.0 // indirect + github.com/swaggo/swag v1.8.1 // indirect + github.com/zeebo/xxh3 v1.0.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/tools v0.35.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gorm.io/driver/mysql v1.5.6 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a4cec28 --- /dev/null +++ b/go.sum @@ -0,0 +1,236 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs= +github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= +github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHcQQP0w= +github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw= +github.com/coreos/go-oidc/v3 v3.16.0 h1:qRQUCFstKpXwmEjDQTIbyY/5jF00+asXzSkmkoa/mow= +github.com/coreos/go-oidc/v3 v3.16.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= +github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= +github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE= +github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= +github.com/go-chi/httprate v0.15.0 h1:j54xcWV9KGmPf/X4H32/aTH+wBlrvxL7P+SdnRqxh5g= +github.com/go-chi/httprate v0.15.0/go.mod h1:rzGHhVrsBn3IMLYDOZQsSU4fJNWcjui4fWKJcCId1R4= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= +github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= +github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= +github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= +github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= +github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA= +github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= +github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= +github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/sv-tools/openapi v0.2.1 h1:ES1tMQMJFGibWndMagvdoo34T1Vllxr1Nlm5wz6b1aA= +github.com/sv-tools/openapi v0.2.1/go.mod h1:k5VuZamTw1HuiS9p2Wl5YIDWzYnHG6/FgPOSFXLAhGg= +github.com/swaggo/files/v2 v2.0.0 h1:hmAt8Dkynw7Ssz46F6pn8ok6YmGZqHSVLZ+HQM7i0kw= +github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM= +github.com/swaggo/http-swagger/v2 v2.0.2 h1:FKCdLsl+sFCx60KFsyM0rDarwiUSZ8DqbfSyIKC9OBg= +github.com/swaggo/http-swagger/v2 v2.0.2/go.mod h1:r7/GBkAWIfK6E/OLnE8fXnviHiDeAHmgIyooa4xm3AQ= +github.com/swaggo/swag v1.8.1 h1:JuARzFX1Z1njbCGz+ZytBR15TFJwF2Q7fu8puJHhQYI= +github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ= +github.com/swaggo/swag/v2 v2.0.0-rc4 h1:SZ8cK68gcV6cslwrJMIOqPkJELRwq4gmjvk77MrvHvY= +github.com/swaggo/swag/v2 v2.0.0-rc4/go.mod h1:Ow7Y8gF16BTCDn8YxZbyKn8FkMLRUHekv1kROJZpbvE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= +golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= +golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/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= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/datatypes v1.2.7 h1:ww9GAhF1aGXZY3EB3cJPJ7//JiuQo7DlQA7NNlVaTdk= +gorm.io/datatypes v1.2.7/go.mod h1:M2iO+6S3hhi4nAyYe444Pcb0dcIiOMJ7QHaUXxyiNZY= +gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8= +gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= +gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= +gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo= +gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= +gorm.io/driver/sqlserver v1.6.0 h1:VZOBQVsVhkHU/NzNhRJKoANt5pZGQAS1Bwc6m6dgfnc= +gorm.io/driver/sqlserver v1.6.0/go.mod h1:WQzt4IJo/WHKnckU9jXBLMJIVNMVeTu25dnOzehntWw= +gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY= +gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= diff --git a/internal/api/httpmiddleware/auth.go b/internal/api/httpmiddleware/auth.go new file mode 100644 index 0000000..984c18d --- /dev/null +++ b/internal/api/httpmiddleware/auth.go @@ -0,0 +1,161 @@ +package httpmiddleware + +import ( + "net/http" + "strings" + + "github.com/glueops/autoglue/internal/auth" + "github.com/glueops/autoglue/internal/models" + "github.com/glueops/autoglue/internal/utils" + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + "gorm.io/gorm" +) + +// AuthMiddleware authenticates either a user principal (JWT, user API key, app key/secret) +// or an org principal (org key/secret). If requireOrg is true, the request must have +// an organization resolved; otherwise org is optional. +// +// Org resolution order for user principals (when requireOrg == true): +// 1. X-Org-ID header (UUID) +// 2. chi URL param {id} (useful under /orgs/{id}/... routers) +// 3. single-membership fallback (exactly one membership) +// +// If none resolves, respond with org_required. +func AuthMiddleware(db *gorm.DB, requireOrg bool) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var user *models.User + var org *models.Organization + var roles []string + + // --- 1) Authenticate principal --- + // Prefer org principal if explicit machine access is provided. + if orgKey := r.Header.Get("X-ORG-KEY"); orgKey != "" { + secret := r.Header.Get("X-ORG-SECRET") + org = auth.ValidateOrgKeyPair(orgKey, secret, db) + if org == nil { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "invalid org credentials") + return + } + // org principal implies machine role + roles = []string{"org:machine"} + } else { + // User principals + if ah := r.Header.Get("Authorization"); strings.HasPrefix(ah, "Bearer ") { + user = auth.ValidateJWT(ah[7:], db) + } else if apiKey := r.Header.Get("X-API-KEY"); apiKey != "" { + user = auth.ValidateAPIKey(apiKey, db) + } else if appKey := r.Header.Get("X-APP-KEY"); appKey != "" { + secret := r.Header.Get("X-APP-SECRET") + user = auth.ValidateAppKeyPair(appKey, secret, db) + } + + if user == nil { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "invalid credentials") + return + } + + // --- 2) Resolve organization (user principal) --- + // A) Try X-Org-ID if present + if s := r.Header.Get("X-Org-ID"); s != "" { + oid, err := uuid.Parse(s) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "invalid_org_id", "X-Org-ID must be a UUID") + return + } + var o models.Organization + if err := db.First(&o, "id = ?", oid).Error; err != nil { + // Header provided but org not found + utils.WriteError(w, http.StatusUnauthorized, "org_forbidden", "organization not found") + return + } + // Verify membership + if !userIsMember(db, user.ID, o.ID) { + utils.WriteError(w, http.StatusUnauthorized, "org_forbidden", "user is not a member of specified org") + return + } + org = &o + } + + // B) If still no org and requireOrg==true, try chi URL param {id} + if org == nil && requireOrg { + if sid := chi.URLParam(r, "id"); sid != "" { + if oid, err := uuid.Parse(sid); err == nil { + var o models.Organization + if err := db.First(&o, "id = ?", oid).Error; err == nil && userIsMember(db, user.ID, o.ID) { + org = &o + } else { + utils.WriteError(w, http.StatusUnauthorized, "org_forbidden", "user is not a member of specified org") + return + } + } + } + } + + // C) Single-membership fallback (only if requireOrg==true and still nil) + if org == nil && requireOrg { + var ms []models.Membership + if err := db.Where("user_id = ?", user.ID).Find(&ms).Error; err == nil && len(ms) == 1 { + var o models.Organization + if err := db.First(&o, "id = ?", ms[0].OrganizationID).Error; err == nil { + org = &o + } + } + } + + // D) Final check + if requireOrg && org == nil { + utils.WriteError(w, http.StatusUnauthorized, "org_required", "specify X-Org-ID or use an endpoint that does not require org") + return + } + + // Populate roles if an org was resolved (optional for org-optional endpoints) + if org != nil { + roles = userRolesInOrg(db, user.ID, org.ID) + if len(roles) == 0 { + utils.WriteError(w, http.StatusForbidden, "forbidden", "no roles in organization") + return + } + } + } + + // --- 3) Attach to context and proceed --- + ctx := r.Context() + if user != nil { + ctx = WithUser(ctx, user) + } + if org != nil { + ctx = WithOrg(ctx, org) + } + if roles != nil { + ctx = WithRoles(ctx, roles) + } + + next.ServeHTTP(w, r.WithContext(ctx)) + }) + } +} + +func userIsMember(db *gorm.DB, userID, orgID uuid.UUID) bool { + var count int64 + db.Model(&models.Membership{}). + Where("user_id = ? AND organization_id = ?", userID, orgID). + Count(&count) + return count > 0 +} + +func userRolesInOrg(db *gorm.DB, userID, orgID uuid.UUID) []string { + var m models.Membership + if err := db.Where("user_id = ? AND organization_id = ?", userID, orgID).First(&m).Error; err == nil { + switch m.Role { + case "owner": + return []string{"role:owner", "role:admin", "role:member"} + case "admin": + return []string{"role:admin", "role:member"} + default: + return []string{"role:member"} + } + } + return nil +} diff --git a/internal/api/httpmiddleware/context.go b/internal/api/httpmiddleware/context.go new file mode 100644 index 0000000..81c8f75 --- /dev/null +++ b/internal/api/httpmiddleware/context.go @@ -0,0 +1,45 @@ +package httpmiddleware + +import ( + "context" + + "github.com/glueops/autoglue/internal/models" + "github.com/google/uuid" +) + +type ctxKey string + +const ( + ctxUserKey ctxKey = "ctx_user" + ctxOrgKey ctxKey = "ctx_org" + ctxRolesKey ctxKey = "ctx_roles" // []string, user roles in current org +) + +func WithUser(ctx context.Context, u *models.User) context.Context { + return context.WithValue(ctx, ctxUserKey, u) +} +func WithOrg(ctx context.Context, o *models.Organization) context.Context { + return context.WithValue(ctx, ctxOrgKey, o) +} +func WithRoles(ctx context.Context, roles []string) context.Context { + return context.WithValue(ctx, ctxRolesKey, roles) +} + +func UserFrom(ctx context.Context) (*models.User, bool) { + u, ok := ctx.Value(ctxUserKey).(*models.User) + return u, ok && u != nil +} +func OrgFrom(ctx context.Context) (*models.Organization, bool) { + o, ok := ctx.Value(ctxOrgKey).(*models.Organization) + return o, ok && o != nil +} +func OrgIDFrom(ctx context.Context) (uuid.UUID, bool) { + if o, ok := OrgFrom(ctx); ok { + return o.ID, true + } + return uuid.Nil, false +} +func RolesFrom(ctx context.Context) ([]string, bool) { + r, ok := ctx.Value(ctxRolesKey).([]string) + return r, ok && r != nil +} diff --git a/internal/api/httpmiddleware/rbac.go b/internal/api/httpmiddleware/rbac.go new file mode 100644 index 0000000..e630a7e --- /dev/null +++ b/internal/api/httpmiddleware/rbac.go @@ -0,0 +1,45 @@ +package httpmiddleware + +import ( + "net/http" + + "github.com/glueops/autoglue/internal/utils" +) + +func RequireRole(minRole string) func(http.Handler) http.Handler { + // order: owner > admin > member + rank := map[string]int{ + "role:member": 1, + "role:admin": 2, + "role:owner": 3, + "org:machine": 2, + "org:machine:ro": 1, + } + need := map[string]bool{ + "member": true, "admin": true, "owner": true, + } + if !need[minRole] { + minRole = "member" + } + + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + roles, ok := RolesFrom(r.Context()) + if !ok || len(roles) == 0 { + utils.WriteError(w, http.StatusForbidden, "forbidden", "no roles in context") + return + } + max := 0 + for _, ro := range roles { + if rank[ro] > max { + max = rank[ro] + } + } + if max < rank["role:"+minRole] { + utils.WriteError(w, http.StatusForbidden, "forbidden", "insufficient role") + return + } + next.ServeHTTP(w, r) + }) + } +} diff --git a/internal/api/mw_logger.go b/internal/api/mw_logger.go new file mode 100644 index 0000000..232940d --- /dev/null +++ b/internal/api/mw_logger.go @@ -0,0 +1,35 @@ +package api + +import ( + "net/http" + "time" + + "github.com/go-chi/chi/v5/middleware" + "github.com/rs/zerolog/log" +) + +func zeroLogMiddleware() func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor) + start := time.Now() + + next.ServeHTTP(ww, r) + + dur := time.Since(start) + ev := log.Info() + if ww.Status() >= 500 { + ev = log.Error() + } + ev. + Str("remote_ip", r.RemoteAddr). + Str("request_id", middleware.GetReqID(r.Context())). + Str("method", r.Method). + Str("path", r.URL.Path). + Int("status", ww.Status()). + Int("bytes", ww.BytesWritten()). + Dur("duration", dur). + Msg("http_request") + }) + } +} diff --git a/internal/api/mw_security.go b/internal/api/mw_security.go new file mode 100644 index 0000000..b0a5cab --- /dev/null +++ b/internal/api/mw_security.go @@ -0,0 +1,63 @@ +package api + +import ( + "net/http" + "strings" + + "github.com/glueops/autoglue/internal/config" +) + +func SecurityHeaders(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // HSTS (enable only over TLS/behind HTTPS) + // HSTS only when not in dev and over TLS/behind a proxy that terminates TLS + if !config.IsDev() { + w.Header().Set("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload") + } + + w.Header().Set("X-Frame-Options", "DENY") + w.Header().Set("X-Content-Type-Options", "nosniff") + w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin") + w.Header().Set("Permissions-Policy", "geolocation=(), camera=(), microphone=(), interest-cohort=()") + + if config.IsDev() { + // --- Relaxed CSP for Vite dev server & Google Fonts --- + // Allows inline/eval for React Refresh preamble, HMR websocket, and fonts. + // Tighten these as you move to prod or self-host fonts. + w.Header().Set("Content-Security-Policy", strings.Join([]string{ + "default-src 'self'", + "base-uri 'self'", + "form-action 'self'", + // Vite dev & inline preamble/eval: + "script-src 'self' 'unsafe-inline' 'unsafe-eval' http://localhost:5173", + // allow dev style + Google Fonts + "style-src 'self' 'unsafe-inline' http://localhost:5173 https://fonts.googleapis.com", + "img-src 'self' data: blob:", + // Google font files + "font-src 'self' data: https://fonts.gstatic.com", + // HMR connections + "connect-src 'self' http://localhost:5173 ws://localhost:5173 ws://localhost:8080", + "frame-ancestors 'none'", + }, "; ")) + } else { + // --- Strict CSP for production --- + // If you keep using Google Fonts in prod, add: + // style-src ... https://fonts.googleapis.com + // font-src ... https://fonts.gstatic.com + // Recommended: self-host fonts in prod and keep these tight. + w.Header().Set("Content-Security-Policy", strings.Join([]string{ + "default-src 'self'", + "base-uri 'self'", + "form-action 'self'", + "script-src 'self'", + "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", + "img-src 'self' data: blob:", + "font-src 'self' data: https://fonts.gstatic.com", + "connect-src 'self'", + "frame-ancestors 'none'", + }, "; ")) + } + + next.ServeHTTP(w, r) + }) +} diff --git a/internal/api/routes.go b/internal/api/routes.go new file mode 100644 index 0000000..af0066b --- /dev/null +++ b/internal/api/routes.go @@ -0,0 +1,195 @@ +package api + +import ( + "fmt" + "net/http" + httpPprof "net/http/pprof" + "os" + "time" + + "github.com/glueops/autoglue/docs" + "github.com/glueops/autoglue/internal/api/httpmiddleware" + "github.com/glueops/autoglue/internal/config" + "github.com/glueops/autoglue/internal/handlers" + "github.com/glueops/autoglue/internal/web" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" + "github.com/go-chi/cors" + "github.com/go-chi/httprate" + + "gorm.io/gorm" + + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + + httpSwagger "github.com/swaggo/http-swagger/v2" +) + +func NewRouter(db *gorm.DB) http.Handler { + zerolog.TimeFieldFormat = time.RFC3339 + + l := log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: "15:04:05"}) + log.Logger = l + + r := chi.NewRouter() + r.Use(middleware.RequestID) + r.Use(middleware.RealIP) + r.Use(zeroLogMiddleware()) + r.Use(middleware.Recoverer) + r.Use(SecurityHeaders) + r.Use(requestBodyLimit(10 << 20)) + r.Use(httprate.LimitByIP(100, 1*time.Minute)) + + allowed := getAllowedOrigins() + r.Use(cors.Handler(cors.Options{ + AllowedOrigins: allowed, + AllowedMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"}, + AllowedHeaders: []string{ + "Content-Type", + "Authorization", + "X-Org-ID", + "X-API-KEY", + "X-ORG-KEY", + "X-ORG-SECRET", + }, + ExposedHeaders: []string{"Link"}, + AllowCredentials: true, + MaxAge: 600, + })) + + r.Use(middleware.AllowContentType("application/json")) + + r.Get("/.well-known/jwks.json", handlers.JWKSHandler) + r.Route("/api", func(api chi.Router) { + api.Route("/v1", func(v1 chi.Router) { + authUser := httpmiddleware.AuthMiddleware(db, false) + authOrg := httpmiddleware.AuthMiddleware(db, true) + + // Also serving a versioned JWKS for swagger, which uses BasePath + v1.Get("/.well-known/jwks.json", handlers.JWKSHandler) + + v1.Route("/auth", func(a chi.Router) { + a.Post("/{provider}/start", handlers.AuthStart(db)) + a.Get("/{provider}/callback", handlers.AuthCallback(db)) + a.Post("/refresh", handlers.Refresh(db)) + a.Post("/logout", handlers.Logout(db)) + }) + + v1.Route("/me", func(me chi.Router) { + me.Use(authUser) + + me.Get("/", handlers.GetMe(db)) + me.Patch("/", handlers.UpdateMe(db)) + + me.Get("/api-keys", handlers.ListUserAPIKeys(db)) + me.Post("/api-keys", handlers.CreateUserAPIKey(db)) + me.Delete("/api-keys/{id}", handlers.DeleteUserAPIKey(db)) + }) + + v1.Route("/orgs", func(o chi.Router) { + o.Use(authUser) + o.Get("/", handlers.ListMyOrgs(db)) + o.Post("/", handlers.CreateOrg(db)) + + o.Group(func(og chi.Router) { + og.Use(authOrg) + og.Get("/{id}", handlers.GetOrg(db)) + og.Patch("/{id}", handlers.UpdateOrg(db)) + og.Delete("/{id}", handlers.DeleteOrg(db)) + + // members + og.Get("/{id}/members", handlers.ListMembers(db)) + og.Post("/{id}/members", handlers.AddOrUpdateMember(db)) + og.Delete("/{id}/members/{user_id}", handlers.RemoveMember(db)) + + // org-scoped key/secret pair + og.Get("/{id}/api-keys", handlers.ListOrgKeys(db)) + og.Post("/{id}/api-keys", handlers.CreateOrgKey(db)) + og.Delete("/{id}/api-keys/{key_id}", handlers.DeleteOrgKey(db)) + }) + }) + + v1.Route("/ssh", func(s chi.Router) { + s.Use(authOrg) + s.Get("/", handlers.ListPublicSshKeys(db)) + s.Post("/", handlers.CreateSSHKey(db)) + s.Get("/{id}", handlers.GetSSHKey(db)) + s.Delete("/{id}", handlers.DeleteSSHKey(db)) + s.Get("/{id}/download", handlers.DownloadSSHKey(db)) + }) + + v1.Route("/servers", func(s chi.Router) { + s.Use(authOrg) + s.Get("/", handlers.ListServers(db)) + s.Post("/", handlers.CreateServer(db)) + s.Get("/{id}", handlers.GetServer(db)) + s.Patch("/{id}", handlers.UpdateServer(db)) + s.Delete("/{id}", handlers.DeleteServer(db)) + }) + + v1.Route("/taints", func(s chi.Router) { + s.Use(authOrg) + s.Get("/", handlers.ListTaints(db)) + s.Post("/", handlers.CreateTaint(db)) + s.Get("/{id}", handlers.GetTaint(db)) + s.Patch("/{id}", handlers.UpdateTaint(db)) + s.Delete("/{id}", handlers.DeleteTaint(db)) + }) + }) + }) + if config.IsDebug() { + r.Route("/debug/pprof", func(pr chi.Router) { + pr.Get("/", httpPprof.Index) + pr.Get("/cmdline", httpPprof.Cmdline) + pr.Get("/profile", httpPprof.Profile) + pr.Get("/symbol", httpPprof.Symbol) + pr.Get("/trace", httpPprof.Trace) + + pr.Handle("/allocs", httpPprof.Handler("allocs")) + pr.Handle("/block", httpPprof.Handler("block")) + pr.Handle("/goroutine", httpPprof.Handler("goroutine")) + pr.Handle("/heap", httpPprof.Handler("heap")) + pr.Handle("/mutex", httpPprof.Handler("mutex")) + pr.Handle("/threadcreate", httpPprof.Handler("threadcreate")) + }) + } + + if config.IsSwaggerEnabled() { + r.Get("/swagger/*", httpSwagger.Handler( + httpSwagger.URL("swagger.json"), + )) + r.Get("/swagger/swagger.json", serveSwaggerFromEmbed(docs.SwaggerJSON, "application/json")) + r.Get("/swagger/swagger.yaml", serveSwaggerFromEmbed(docs.SwaggerYAML, "application/x-yaml")) + } + + if config.IsUIDev() { + fmt.Println("Running in development mode") + // Dev: isolate proxy from chi middlewares so WS upgrade can hijack. + proxy, err := web.DevProxy("http://localhost:5173") + if err != nil { + log.Error().Err(err).Msg("dev proxy init failed") + return r // fallback + } + + mux := http.NewServeMux() + // Send API/Swagger/pprof to chi + mux.Handle("/api/", r) + mux.Handle("/api", r) + mux.Handle("/swagger/", r) + mux.Handle("/debug/pprof/", r) + // Everything else (/, /brand-preview, assets) → proxy (no middlewares) + mux.Handle("/", proxy) + + return mux + } else { + fmt.Println("Running in production mode") + if h, err := web.SPAHandler(); err == nil { + r.NotFound(h.ServeHTTP) + } else { + log.Error().Err(err).Msg("spa handler init failed") + } + } + + return r +} diff --git a/internal/api/utils.go b/internal/api/utils.go new file mode 100644 index 0000000..e9ba419 --- /dev/null +++ b/internal/api/utils.go @@ -0,0 +1,45 @@ +package api + +import ( + "net/http" + "os" + "strings" +) + +func requestBodyLimit(maxBytes int64) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r.Body = http.MaxBytesReader(w, r.Body, maxBytes) + next.ServeHTTP(w, r) + }) + } +} + +func getAllowedOrigins() []string { + if v := os.Getenv("CORS_ALLOWED_ORIGINS"); v != "" { + parts := strings.Split(v, ",") + out := make([]string, 0, len(parts)) + for _, p := range parts { + s := strings.TrimSpace(p) + if s != "" { + out = append(out, s) + } + } + if len(out) > 0 { + return out + } + } + // Defaults (dev) + return []string{ + "http://localhost:5173", + "http://localhost:8080", + } +} + +func serveSwaggerFromEmbed(data []byte, contentType string) http.HandlerFunc { + return func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", contentType) + w.WriteHeader(http.StatusOK) + _, _ = w.Write(data) + } +} diff --git a/internal/app/runtime.go b/internal/app/runtime.go new file mode 100644 index 0000000..5665184 --- /dev/null +++ b/internal/app/runtime.go @@ -0,0 +1,46 @@ +package app + +import ( + "log" + + "github.com/glueops/autoglue/internal/config" + "github.com/glueops/autoglue/internal/db" + "github.com/glueops/autoglue/internal/models" + "gorm.io/gorm" +) + +type Runtime struct { + Cfg config.Config + DB *gorm.DB +} + +func NewRuntime() *Runtime { + cfg, err := config.Load() + if err != nil { + log.Fatal(err) + } + d := db.Open(cfg.DbURL) + + err = db.Run(d, + &models.MasterKey{}, + &models.SigningKey{}, + &models.User{}, + &models.Organization{}, + &models.Account{}, + &models.Membership{}, + &models.APIKey{}, + &models.UserEmail{}, + &models.RefreshToken{}, + &models.OrganizationKey{}, + &models.SshKey{}, + &models.Server{}, + &models.Taint{}, + ) + if err != nil { + log.Fatalf("Error initializing database: %v", err) + } + return &Runtime{ + Cfg: cfg, + DB: d, + } +} diff --git a/internal/auth/hash.go b/internal/auth/hash.go new file mode 100644 index 0000000..a0eaf1e --- /dev/null +++ b/internal/auth/hash.go @@ -0,0 +1,38 @@ +package auth + +import ( + "crypto/sha256" + "encoding/hex" + "errors" + "time" + + "github.com/alexedwards/argon2id" +) + +func SHA256Hex(s string) string { + sum := sha256.Sum256([]byte(s)) + return hex.EncodeToString(sum[:]) +} + +var argonParams = &argon2id.Params{ + Memory: 64 * 1024, // 64MB + Iterations: 3, + Parallelism: 2, + SaltLength: 16, + KeyLength: 32, +} + +func HashSecretArgon2id(plain string) (string, error) { + return argon2id.CreateHash(plain, argonParams) +} + +func VerifySecretArgon2id(encodedHash, plain string) (bool, error) { + if encodedHash == "" { + return false, errors.New("empty hash") + } + return argon2id.ComparePasswordAndHash(plain, encodedHash) +} + +func NotExpired(expiresAt *time.Time) bool { + return expiresAt == nil || time.Now().Before(*expiresAt) +} diff --git a/internal/auth/issue.go b/internal/auth/issue.go new file mode 100644 index 0000000..bdbd0a5 --- /dev/null +++ b/internal/auth/issue.go @@ -0,0 +1,42 @@ +package auth + +import ( + "crypto/rand" + "encoding/base64" + "time" + + "github.com/glueops/autoglue/internal/models" + "github.com/google/uuid" + "gorm.io/gorm" +) + +func randomToken(n int) (string, error) { + b := make([]byte, n) + if _, err := rand.Read(b); err != nil { + return "", err + } + // URL-safe, no padding + return base64.RawURLEncoding.EncodeToString(b), nil +} + +// IssueUserAPIKey creates a single-token user API key (X-API-KEY) +func IssueUserAPIKey(db *gorm.DB, userID uuid.UUID, name string, ttl *time.Duration) (plaintext string, rec models.APIKey, err error) { + plaintext, err = randomToken(32) + if err != nil { + return "", models.APIKey{}, err + } + rec = models.APIKey{ + Name: name, + Scope: "user", + UserID: &userID, + KeyHash: SHA256Hex(plaintext), // deterministic lookup + } + if ttl != nil { + ex := time.Now().Add(*ttl) + rec.ExpiresAt = &ex + } + if err = db.Create(&rec).Error; err != nil { + return "", models.APIKey{}, err + } + return plaintext, rec, nil +} diff --git a/internal/auth/jwks_export.go b/internal/auth/jwks_export.go new file mode 100644 index 0000000..30bb8d9 --- /dev/null +++ b/internal/auth/jwks_export.go @@ -0,0 +1,71 @@ +package auth + +import ( + "crypto/ed25519" + "crypto/rsa" + "encoding/base64" + "fmt" + "math/big" +) + +// base64url (no padding) +func b64url(b []byte) string { + return base64.RawURLEncoding.EncodeToString(b) +} + +// convert small int (RSA exponent) to big-endian bytes +func fromInt(i int) []byte { + var x big.Int + x.SetInt64(int64(i)) + return x.Bytes() +} + +// --- public accessors for JWKS --- + +// KeyMeta is a minimal metadata view exposed for JWKS rendering. +type KeyMeta struct { + Alg string +} + +// MetaFor returns minimal metadata (currently the alg) for a given kid. +// If not found, returns zero value (Alg == ""). +func MetaFor(kid string) KeyMeta { + kc.mu.RLock() + defer kc.mu.RUnlock() + if m, ok := kc.meta[kid]; ok { + return KeyMeta{Alg: m.Alg} + } + return KeyMeta{} +} + +// KcCopy invokes fn with a shallow copy of the public key map (kid -> public key instance). +// Useful to iterate without holding the lock during JSON building. +func KcCopy(fn func(map[string]interface{})) { + kc.mu.RLock() + defer kc.mu.RUnlock() + out := make(map[string]interface{}, len(kc.pub)) + for kid, pk := range kc.pub { + out[kid] = pk + } + fmt.Println(out) + fn(out) +} + +// PubToJWK converts a parsed public key into bare JWK parameters + kty. +// - RSA: returns n/e (base64url) and kty="RSA" +// - Ed25519: returns x (base64url) and kty="OKP" +func PubToJWK(_kid, _alg string, pub any) (map[string]string, string) { + switch k := pub.(type) { + case *rsa.PublicKey: + return map[string]string{ + "n": b64url(k.N.Bytes()), + "e": b64url(fromInt(k.E)), + }, "RSA" + case ed25519.PublicKey: + return map[string]string{ + "x": b64url([]byte(k)), + }, "OKP" + default: + return nil, "" + } +} diff --git a/internal/auth/jwt_issue.go b/internal/auth/jwt_issue.go new file mode 100644 index 0000000..ed7c6d9 --- /dev/null +++ b/internal/auth/jwt_issue.go @@ -0,0 +1,55 @@ +package auth + +import ( + "errors" + "time" + + "github.com/golang-jwt/jwt/v5" +) + +type IssueOpts struct { + Subject string + Issuer string + Audience string + TTL time.Duration + Claims map[string]any // extra app claims +} + +func IssueAccessToken(opts IssueOpts) (string, error) { + kc.mu.RLock() + defer kc.mu.RUnlock() + + if kc.selPriv == nil || kc.selKid == "" || kc.selAlg == "" { + return "", errors.New("no active signing key") + } + + claims := jwt.MapClaims{ + "iss": opts.Issuer, + "aud": opts.Audience, + "sub": opts.Subject, + "iat": time.Now().Unix(), + "exp": time.Now().Add(opts.TTL).Unix(), + } + for k, v := range opts.Claims { + claims[k] = v + } + + var method jwt.SigningMethod + switch kc.selAlg { + case "RS256": + method = jwt.SigningMethodRS256 + case "RS384": + method = jwt.SigningMethodRS384 + case "RS512": + method = jwt.SigningMethodRS512 + case "EdDSA": + method = jwt.SigningMethodEdDSA + default: + return "", errors.New("unsupported alg") + } + + token := jwt.NewWithClaims(method, claims) + token.Header["kid"] = kc.selKid + + return token.SignedString(kc.selPriv) +} diff --git a/internal/auth/jwt_signer.go b/internal/auth/jwt_signer.go new file mode 100644 index 0000000..e339509 --- /dev/null +++ b/internal/auth/jwt_signer.go @@ -0,0 +1,138 @@ +package auth + +import ( + "crypto/ed25519" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "sync" + "time" + + "github.com/glueops/autoglue/internal/keys" + "github.com/glueops/autoglue/internal/models" + "gorm.io/gorm" +) + +type keyCache struct { + mu sync.RWMutex + pub map[string]interface{} // kid -> public key object + meta map[string]models.SigningKey + selKid string + selAlg string + selPriv any +} + +var kc keyCache + +// Refresh loads active keys into memory. Call on startup and periodically (ticker/cron). +func Refresh(db *gorm.DB, encKeyB64 string) error { + var rows []models.SigningKey + if err := db.Where("is_active = true AND (expires_at IS NULL OR expires_at > ?)", time.Now()). + Order("created_at desc").Find(&rows).Error; err != nil { + return err + } + + pub := make(map[string]interface{}, len(rows)) + meta := make(map[string]models.SigningKey, len(rows)) + var selKid string + var selAlg string + var selPriv any + + for i, r := range rows { + // parse public + block, _ := pem.Decode([]byte(r.PublicPEM)) + if block == nil { + continue + } + var pubKey any + switch r.Alg { + case "RS256", "RS384", "RS512": + pubKey, _ = x509.ParsePKCS1PublicKey(block.Bytes) + if pubKey == nil { + // also allow PKIX format + if k, err := x509.ParsePKIXPublicKey(block.Bytes); err == nil { + pubKey = k + } + } + case "EdDSA": + k, err := x509.ParsePKIXPublicKey(block.Bytes) + if err == nil { + if edk, ok := k.(ed25519.PublicKey); ok { + pubKey = edk + } + } + } + if pubKey == nil { + continue + } + pub[r.Kid] = pubKey + meta[r.Kid] = r + + // pick first row as current signer (most recent because of order desc) + if i == 0 { + privPEM := r.PrivatePEM + // decrypt if necessary + if len(privPEM) > 10 && privPEM[:10] == "enc:aesgcm" { + pt, err := keysDecrypt(encKeyB64, privPEM) + if err != nil { + continue + } + privPEM = string(pt) + } + blockPriv, _ := pem.Decode([]byte(privPEM)) + if blockPriv == nil { + continue + } + switch r.Alg { + case "RS256", "RS384", "RS512": + if k, err := x509.ParsePKCS1PrivateKey(blockPriv.Bytes); err == nil { + selPriv = k + selAlg = r.Alg + selKid = r.Kid + } else if kAny, err := x509.ParsePKCS8PrivateKey(blockPriv.Bytes); err == nil { + if k, ok := kAny.(*rsa.PrivateKey); ok { + selPriv = k + selAlg = r.Alg + selKid = r.Kid + } + } + case "EdDSA": + if kAny, err := x509.ParsePKCS8PrivateKey(blockPriv.Bytes); err == nil { + if k, ok := kAny.(ed25519.PrivateKey); ok { + selPriv = k + selAlg = r.Alg + selKid = r.Kid + } + } + } + } + } + + kc.mu.Lock() + defer kc.mu.Unlock() + kc.pub = pub + kc.meta = meta + kc.selKid = selKid + kc.selAlg = selAlg + kc.selPriv = selPriv + return nil +} + +func keysDecrypt(encKey, enc string) ([]byte, error) { + return keysDecryptImpl(encKey, enc) +} + +// indirection for same package +var keysDecryptImpl = func(encKey, enc string) ([]byte, error) { + return nil, errors.New("not wired") +} + +// Wire up from keys package +func init() { + keysDecryptImpl = keysDecryptShim +} + +func keysDecryptShim(encKey, enc string) ([]byte, error) { + return keys.Decrypt(encKey, enc) +} diff --git a/internal/auth/jwt_validate.go b/internal/auth/jwt_validate.go new file mode 100644 index 0000000..e23dbf8 --- /dev/null +++ b/internal/auth/jwt_validate.go @@ -0,0 +1,56 @@ +package auth + +import ( + "github.com/glueops/autoglue/internal/config" + "github.com/glueops/autoglue/internal/models" + "github.com/golang-jwt/jwt/v5" + "github.com/google/uuid" + "gorm.io/gorm" +) + +// ValidateJWT verifies RS256/RS384/RS512/EdDSA tokens using the in-memory key cache. +// It honors kid when present, and falls back to any active key. +func ValidateJWT(tokenStr string, db *gorm.DB) *models.User { + cfg, _ := config.Load() + + parser := jwt.NewParser( + jwt.WithIssuer(cfg.JWTIssuer), + jwt.WithAudience(cfg.JWTAudience), + jwt.WithValidMethods([]string{"RS256", "RS384", "RS512", "EdDSA"}), + ) + + token, err := parser.Parse(tokenStr, func(t *jwt.Token) (any, error) { + // Resolve by kid first + kid, _ := t.Header["kid"].(string) + + kc.mu.RLock() + defer kc.mu.RUnlock() + + if kid != "" { + if k, ok := kc.pub[kid]; ok { + return k, nil + } + } + // Fallback: try first active key + for _, k := range kc.pub { + return k, nil + } + return nil, jwt.ErrTokenUnverifiable + }) + if err != nil || !token.Valid { + return nil + } + + claims, _ := token.Claims.(jwt.MapClaims) + sub, _ := claims["sub"].(string) + uid, err := uuid.Parse(sub) + if err != nil { + return nil + } + + var u models.User + if err := db.First(&u, "id = ? AND is_disabled = false", uid).Error; err != nil { + return nil + } + return &u +} diff --git a/internal/auth/refresh.go b/internal/auth/refresh.go new file mode 100644 index 0000000..86de9c2 --- /dev/null +++ b/internal/auth/refresh.go @@ -0,0 +1,105 @@ +package auth + +import ( + "crypto/rand" + "encoding/base64" + "errors" + "time" + + "github.com/glueops/autoglue/internal/models" + "github.com/google/uuid" + "gorm.io/gorm" +) + +// random opaque token (returned to client once) +func generateOpaqueToken(n int) (string, error) { + b := make([]byte, n) + if _, err := rand.Read(b); err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(b), nil +} + +type RefreshPair struct { + Plain string + Record models.RefreshToken +} + +// Issue a new refresh token (new family if familyID == nil) +func IssueRefreshToken(db *gorm.DB, userID uuid.UUID, ttl time.Duration, familyID *uuid.UUID) (RefreshPair, error) { + plain, err := generateOpaqueToken(32) + if err != nil { + return RefreshPair{}, err + } + hash, err := HashSecretArgon2id(plain) + if err != nil { + return RefreshPair{}, err + } + + fid := uuid.New() + if familyID != nil { + fid = *familyID + } + + rec := models.RefreshToken{ + UserID: userID, + FamilyID: fid, + TokenHash: hash, + ExpiresAt: time.Now().Add(ttl), + } + if err := db.Create(&rec).Error; err != nil { + return RefreshPair{}, err + } + return RefreshPair{Plain: plain, Record: rec}, nil +} + +// ValidateRefreshToken refresh token; returns record if valid & not revoked/expired +func ValidateRefreshToken(db *gorm.DB, plain string) (*models.RefreshToken, error) { + if plain == "" { + return nil, errors.New("empty") + } + // var rec models.RefreshToken + // We can't query by hash w/ Argon; scan candidates by expiry window. Keep small TTL (e.g. 30d). + if err := db.Where("expires_at > ? AND revoked_at IS NULL", time.Now()). + Find(&[]models.RefreshToken{}).Error; err != nil { + return nil, err + } + // Better: add a prefix column to narrow scan; omitted for brevity. + + // Pragmatic approach: single SELECT per token: + // Add a TokenHashSHA256 column for deterministic lookup if you want O(1). (Optional) + + // Minimal: iterate limited set; for simplicity we fetch by created window: + var recs []models.RefreshToken + if err := db.Where("expires_at > ? AND revoked_at IS NULL", time.Now()). + Order("created_at desc").Limit(500).Find(&recs).Error; err != nil { + return nil, err + } + for _, r := range recs { + ok, _ := VerifySecretArgon2id(r.TokenHash, plain) + if ok { + return &r, nil + } + } + return nil, errors.New("invalid") +} + +// RevokeFamily revokes all tokens in a family (logout everywhere) +func RevokeFamily(db *gorm.DB, familyID uuid.UUID) error { + now := time.Now() + return db.Model(&models.RefreshToken{}). + Where("family_id = ? AND revoked_at IS NULL", familyID). + Update("revoked_at", &now).Error +} + +// RotateRefreshToken replaces one token with a fresh one within the same family +func RotateRefreshToken(db *gorm.DB, used *models.RefreshToken, ttl time.Duration) (RefreshPair, error) { + // revoke the used token (one-time use) + now := time.Now() + if err := db.Model(&models.RefreshToken{}). + Where("id = ? AND revoked_at IS NULL", used.ID). + Update("revoked_at", &now).Error; err != nil { + return RefreshPair{}, err + } + return IssueRefreshToken(db, used.UserID, ttl, &used.FamilyID) +} diff --git a/internal/auth/validate_keys.go b/internal/auth/validate_keys.go new file mode 100644 index 0000000..1b19113 --- /dev/null +++ b/internal/auth/validate_keys.go @@ -0,0 +1,88 @@ +package auth + +import ( + "time" + + "github.com/glueops/autoglue/internal/models" + "gorm.io/gorm" +) + +// ValidateAPIKey validates a single-token user API key sent via X-API-KEY. +func ValidateAPIKey(rawKey string, db *gorm.DB) *models.User { + if rawKey == "" { + return nil + } + digest := SHA256Hex(rawKey) + + var k models.APIKey + if err := db. + Where("key_hash = ? AND scope = ? AND (expires_at IS NULL OR expires_at > ?)", digest, "user", time.Now()). + First(&k).Error; err != nil { + return nil + } + if k.UserID == nil { + return nil + } + var u models.User + if err := db.First(&u, "id = ? AND is_disabled = false", *k.UserID).Error; err != nil { + return nil + } + // Optional: touch last_used_at here if you've added it on the model. + return &u +} + +// ValidateAppKeyPair validates a user key/secret pair via X-APP-KEY / X-APP-SECRET. +func ValidateAppKeyPair(appKey, secret string, db *gorm.DB) *models.User { + if appKey == "" || secret == "" { + return nil + } + digest := SHA256Hex(appKey) + + var k models.APIKey + if err := db. + Where("key_hash = ? AND scope = ? AND (expires_at IS NULL OR expires_at > ?)", digest, "user", time.Now()). + First(&k).Error; err != nil { + return nil + } + ok, _ := VerifySecretArgon2id(zeroIfNil(k.SecretHash), secret) + if !ok || k.UserID == nil { + return nil + } + var u models.User + if err := db.First(&u, "id = ? AND is_disabled = false", *k.UserID).Error; err != nil { + return nil + } + return &u +} + +// ValidateOrgKeyPair validates an org key/secret via X-ORG-KEY / X-ORG-SECRET. +func ValidateOrgKeyPair(orgKey, secret string, db *gorm.DB) *models.Organization { + if orgKey == "" || secret == "" { + return nil + } + digest := SHA256Hex(orgKey) + + var k models.APIKey + if err := db. + Where("key_hash = ? AND scope = ? AND (expires_at IS NULL OR expires_at > ?)", digest, "org", time.Now()). + First(&k).Error; err != nil { + return nil + } + ok, _ := VerifySecretArgon2id(zeroIfNil(k.SecretHash), secret) + if !ok || k.OrgID == nil { + return nil + } + var o models.Organization + if err := db.First(&o, "id = ?", *k.OrgID).Error; err != nil { + return nil + } + return &o +} + +// local helper; avoids nil-deref when comparing secrets +func zeroIfNil(s *string) string { + if s == nil { + return "" + } + return *s +} diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..8a1a939 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,194 @@ +package config + +import ( + "errors" + "fmt" + "strings" + "sync" + + "github.com/joho/godotenv" + "github.com/spf13/viper" + "gopkg.in/yaml.v3" +) + +type Config struct { + DbURL string + Port string + Host string + JWTIssuer string + JWTAudience string + JWTPrivateEncKey string + OAuthRedirectBase string + GoogleClientID string + GoogleClientSecret string + GithubClientID string + GithubClientSecret string + + UIDev bool + Env string + Debug bool + Swagger bool +} + +var ( + once sync.Once + cached Config + loadErr error +) + +func Load() (Config, error) { + once.Do(func() { + _ = godotenv.Load() + + // Use a private viper to avoid global mutation/races + v := viper.New() + + // Defaults + v.SetDefault("bind.address", "127.0.0.1") + v.SetDefault("bind.port", "8080") + v.SetDefault("database.url", "postgres://user:pass@localhost:5432/db?sslmode=disable") + + v.SetDefault("ui.dev", false) + v.SetDefault("env", "development") + v.SetDefault("debug", false) + v.SetDefault("swagger", false) + + // Env setup and binding + v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + v.AutomaticEnv() + + keys := []string{ + "bind.address", + "bind.port", + "database.url", + "jwt.issuer", + "jwt.audience", + "jwt.private.enc.key", + "oauth.redirect.base", + "google.client.id", + "google.client.secret", + "github.client.id", + "github.client.secret", + "ui.dev", + "env", + "debug", + "swagger", + } + for _, k := range keys { + _ = v.BindEnv(k) + } + + // Build config + cfg := Config{ + DbURL: v.GetString("database.url"), + Port: v.GetString("bind.port"), + Host: v.GetString("bind.address"), + JWTIssuer: v.GetString("jwt.issuer"), + JWTAudience: v.GetString("jwt.audience"), + JWTPrivateEncKey: v.GetString("jwt.private.enc.key"), + OAuthRedirectBase: v.GetString("oauth.redirect.base"), + GoogleClientID: v.GetString("google.client.id"), + GoogleClientSecret: v.GetString("google.client.secret"), + GithubClientID: v.GetString("github.client.id"), + GithubClientSecret: v.GetString("github.client.secret"), + + UIDev: v.GetBool("ui.dev"), + Env: v.GetString("env"), + Debug: v.GetBool("debug"), + Swagger: v.GetBool("swagger"), + } + + // Validate + if err := validateConfig(cfg); err != nil { + loadErr = err + return + } + + cached = cfg + }) + return cached, loadErr +} + +func validateConfig(cfg Config) error { + var errs []string + + // Required general settings + req := map[string]string{ + "jwt.issuer": cfg.JWTIssuer, + "jwt.audience": cfg.JWTAudience, + "jwt.private.enc.key": cfg.JWTPrivateEncKey, + "oauth.redirect.base": cfg.OAuthRedirectBase, + } + for k, v := range req { + if strings.TrimSpace(v) == "" { + errs = append(errs, fmt.Sprintf("missing required config key %q (env %s)", k, envNameFromKey(k))) + } + } + + // OAuth provider requirements: + googleOK := strings.TrimSpace(cfg.GoogleClientID) != "" && strings.TrimSpace(cfg.GoogleClientSecret) != "" + githubOK := strings.TrimSpace(cfg.GithubClientID) != "" && strings.TrimSpace(cfg.GithubClientSecret) != "" + + // If partially configured, report what's missing for each + if !googleOK && (cfg.GoogleClientID != "" || cfg.GoogleClientSecret != "") { + if cfg.GoogleClientID == "" { + errs = append(errs, fmt.Sprintf("google.client.id is missing (env %s) while google.client.secret is set", envNameFromKey("google.client.id"))) + } + if cfg.GoogleClientSecret == "" { + errs = append(errs, fmt.Sprintf("google.client.secret is missing (env %s) while google.client.id is set", envNameFromKey("google.client.secret"))) + } + } + if !githubOK && (cfg.GithubClientID != "" || cfg.GithubClientSecret != "") { + if cfg.GithubClientID == "" { + errs = append(errs, fmt.Sprintf("github.client.id is missing (env %s) while github.client.secret is set", envNameFromKey("github.client.id"))) + } + if cfg.GithubClientSecret == "" { + errs = append(errs, fmt.Sprintf("github.client.secret is missing (env %s) while github.client.id is set", envNameFromKey("github.client.secret"))) + } + } + + // Enforce minimum: at least one full provider + if !googleOK && !githubOK { + errs = append(errs, "at least one OAuth provider must be fully configured: either Google (google.client.id + google.client.secret) or GitHub (github.client.id + github.client.secret)") + } + + if len(errs) > 0 { + return errors.New(strings.Join(errs, "; ")) + } + return nil +} + +func envNameFromKey(key string) string { + return strings.ToUpper(strings.ReplaceAll(key, ".", "_")) +} + +func DebugPrintConfig() { + cfg, _ := Load() + b, err := yaml.Marshal(cfg) + if err != nil { + fmt.Println("error marshalling config:", err) + return + } + fmt.Println("Loaded configuration:") + fmt.Println(string(b)) +} + +func IsUIDev() bool { + cfg, _ := Load() + return cfg.UIDev +} + +func IsDev() bool { + cfg, _ := Load() + return strings.EqualFold(cfg.Env, "development") +} + +func IsDebug() bool { + cfg, _ := Load() + return cfg.Debug +} + +func IsSwaggerEnabled() bool { + cfg, _ := Load() + return cfg.Swagger +} diff --git a/internal/db/db.go b/internal/db/db.go new file mode 100644 index 0000000..d28deb8 --- /dev/null +++ b/internal/db/db.go @@ -0,0 +1,17 @@ +package db + +import ( + "log" + + "gorm.io/driver/postgres" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +func Open(dsn string) *gorm.DB { + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{Logger: logger.Default.LogMode(logger.Warn)}) + if err != nil { + log.Fatalf("failed to connect to db: %v", err) + } + return db +} diff --git a/internal/db/migrate.go b/internal/db/migrate.go new file mode 100644 index 0000000..4a16a21 --- /dev/null +++ b/internal/db/migrate.go @@ -0,0 +1,25 @@ +package db + +import ( + "fmt" + + "gorm.io/gorm" +) + +func Run(db *gorm.DB, models ...any) error { + return db.Transaction(func(tx *gorm.DB) error { + // 0) Extensions + if err := tx.Exec(`CREATE EXTENSION IF NOT EXISTS pgcrypto`).Error; err != nil { + return fmt.Errorf("enable pgcrypto: %w", err) + } + if err := tx.Exec(`CREATE EXTENSION IF NOT EXISTS citext`).Error; err != nil { + return fmt.Errorf("enable citext: %w", err) + } + + // 1) AutoMigrate (pass parents before children in caller) + if err := tx.AutoMigrate(models...); err != nil { + return fmt.Errorf("automigrate: %w", err) + } + return nil + }) +} diff --git a/internal/handlers/auth.go b/internal/handlers/auth.go new file mode 100644 index 0000000..9c4e074 --- /dev/null +++ b/internal/handlers/auth.go @@ -0,0 +1,477 @@ +package handlers + +import ( + "context" + "encoding/json" + "net/http" + "net/url" + "strings" + "time" + + "github.com/coreos/go-oidc/v3/oidc" + "github.com/glueops/autoglue/internal/auth" + "github.com/glueops/autoglue/internal/config" + "github.com/glueops/autoglue/internal/handlers/dto" + "github.com/glueops/autoglue/internal/models" + "github.com/glueops/autoglue/internal/utils" + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + "golang.org/x/oauth2" + "gorm.io/gorm" +) + +type oauthProvider struct { + Name string + Issuer string + Scopes []string + ClientID string + Secret string +} + +func providerConfig(cfg config.Config, name string) (oauthProvider, bool) { + switch strings.ToLower(name) { + case "google": + return oauthProvider{ + Name: "google", + Issuer: "https://accounts.google.com", + Scopes: []string{oidc.ScopeOpenID, "email", "profile"}, + ClientID: cfg.GoogleClientID, + Secret: cfg.GoogleClientSecret, + }, true + case "github": + // GitHub is not a pure OIDC provider; we use OAuth2 + user email API + return oauthProvider{ + Name: "github", + Issuer: "github", + Scopes: []string{"read:user", "user:email"}, + ClientID: cfg.GithubClientID, Secret: cfg.GithubClientSecret, + }, true + } + return oauthProvider{}, false +} + +// AuthStart godoc +// @ID AuthStart +// @Summary Begin social login +// @Description Returns provider authorization URL for the frontend to redirect +// @Tags Auth +// @Param provider path string true "google|github" +// @Produce json +// @Success 200 {object} dto.AuthStartResponse +// @Router /auth/{provider}/start [post] +func AuthStart(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + cfg, _ := config.Load() + provider := strings.ToLower(chi.URLParam(r, "provider")) + + p, ok := providerConfig(cfg, provider) + if !ok || p.ClientID == "" || p.Secret == "" { + utils.WriteError(w, http.StatusBadRequest, "unsupported_provider", "provider not configured") + return + } + + redirect := cfg.OAuthRedirectBase + "/api/v1/auth/" + p.Name + "/callback" + + // Optional SPA hints to be embedded into state + mode := r.URL.Query().Get("mode") // "spa" enables postMessage callback page + origin := r.URL.Query().Get("origin") // e.g. http://localhost:5173 + + state := uuid.NewString() + if mode == "spa" && origin != "" { + state = state + "|mode=spa|origin=" + url.QueryEscape(origin) + } + + var authURL string + + if p.Issuer == "github" { + o := &oauth2.Config{ + ClientID: p.ClientID, + ClientSecret: p.Secret, + RedirectURL: redirect, + Scopes: p.Scopes, + Endpoint: oauth2.Endpoint{ + AuthURL: "https://github.com/login/oauth/authorize", + TokenURL: "https://github.com/login/oauth/access_token", + }, + } + authURL = o.AuthCodeURL(state, oauth2.AccessTypeOffline) + } else { + // Google OIDC + ctx := context.Background() + prov, err := oidc.NewProvider(ctx, p.Issuer) + if err != nil { + utils.WriteError(w, http.StatusInternalServerError, "oidc_discovery_failed", err.Error()) + return + } + o := &oauth2.Config{ + ClientID: p.ClientID, + ClientSecret: p.Secret, + RedirectURL: redirect, + Endpoint: prov.Endpoint(), + Scopes: p.Scopes, + } + authURL = o.AuthCodeURL(state, oauth2.AccessTypeOffline) + } + + utils.WriteJSON(w, http.StatusOK, dto.AuthStartResponse{AuthURL: authURL}) + } +} + +// AuthCallback godoc +// @ID AuthCallback +// @Summary Handle social login callback +// @Tags Auth +// @Param provider path string true "google|github" +// @Produce json +// @Success 200 {object} dto.TokenPair +// @Router /auth/{provider}/callback [get] +func AuthCallback(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + cfg, _ := config.Load() + provider := strings.ToLower(chi.URLParam(r, "provider")) + + p, ok := providerConfig(cfg, provider) + if !ok { + utils.WriteError(w, http.StatusBadRequest, "unsupported_provider", "provider not configured") + return + } + + code := r.URL.Query().Get("code") + if code == "" { + utils.WriteError(w, http.StatusBadRequest, "invalid_request", "missing code") + return + } + redirect := cfg.OAuthRedirectBase + "/api/v1/auth/" + p.Name + "/callback" + + var email, display, subject string + + if p.Issuer == "github" { + // OAuth2 code exchange + o := &oauth2.Config{ + ClientID: p.ClientID, + ClientSecret: p.Secret, + RedirectURL: redirect, + Scopes: p.Scopes, + Endpoint: oauth2.Endpoint{ + AuthURL: "https://github.com/login/oauth/authorize", + TokenURL: "https://github.com/login/oauth/access_token", + }, + } + tok, err := o.Exchange(r.Context(), code) + if err != nil { + utils.WriteError(w, http.StatusUnauthorized, "exchange_failed", err.Error()) + return + } + // Fetch user primary email + req, _ := http.NewRequest("GET", "https://api.github.com/user/emails", nil) + req.Header.Set("Authorization", "token "+tok.AccessToken) + resp, err := http.DefaultClient.Do(req) + if err != nil || resp.StatusCode != 200 { + utils.WriteError(w, http.StatusUnauthorized, "email_fetch_failed", "github user/emails") + return + } + defer resp.Body.Close() + var emails []struct { + Email string `json:"email"` + Primary bool `json:"primary"` + Verified bool `json:"verified"` + } + if err := json.NewDecoder(resp.Body).Decode(&emails); err != nil || len(emails) == 0 { + utils.WriteError(w, http.StatusUnauthorized, "email_parse_failed", err.Error()) + return + } + email = emails[0].Email + for _, e := range emails { + if e.Primary { + email = e.Email + break + } + } + subject = "github:" + email + display = strings.Split(email, "@")[0] + } else { + // Google OIDC + oidcProv, err := oidc.NewProvider(r.Context(), p.Issuer) + if err != nil { + utils.WriteError(w, 500, "oidc_discovery_failed", err.Error()) + return + } + o := &oauth2.Config{ + ClientID: p.ClientID, + ClientSecret: p.Secret, + RedirectURL: redirect, + Endpoint: oidcProv.Endpoint(), + Scopes: p.Scopes, + } + tok, err := o.Exchange(r.Context(), code) + if err != nil { + utils.WriteError(w, 401, "exchange_failed", err.Error()) + return + } + + verifier := oidcProv.Verifier(&oidc.Config{ClientID: p.ClientID}) + rawIDToken, ok := tok.Extra("id_token").(string) + if !ok { + utils.WriteError(w, 401, "no_id_token", "") + return + } + idt, err := verifier.Verify(r.Context(), rawIDToken) + if err != nil { + utils.WriteError(w, 401, "id_token_invalid", err.Error()) + return + } + + var claims struct { + Email string `json:"email"` + EmailVerified bool `json:"email_verified"` + Name string `json:"name"` + Sub string `json:"sub"` + } + if err := idt.Claims(&claims); err != nil { + utils.WriteError(w, 401, "claims_parse_error", err.Error()) + return + } + email = strings.ToLower(claims.Email) + display = claims.Name + subject = "google:" + claims.Sub + } + + // Upsert Account + User; domain auto-join (member) + user, err := upsertAccountAndUser(db, p.Name, subject, email, display) + if err != nil { + utils.WriteError(w, 500, "account_upsert_failed", err.Error()) + return + } + + // Org auto-join: Organization.Domain == email domain + _ = ensureAutoMembership(db, user.ID, email) + + // Issue tokens + accessTTL := 1 * time.Hour + refreshTTL := 30 * 24 * time.Hour + + access, err := auth.IssueAccessToken(auth.IssueOpts{ + Subject: user.ID.String(), + Issuer: cfg.JWTIssuer, + Audience: cfg.JWTAudience, + TTL: accessTTL, + Claims: map[string]any{ + "email": email, + "name": display, + }, + }) + if err != nil { + utils.WriteError(w, 500, "issue_access_failed", err.Error()) + return + } + + rp, err := auth.IssueRefreshToken(db, user.ID, refreshTTL, nil) + if err != nil { + utils.WriteError(w, 500, "issue_refresh_failed", err.Error()) + return + } + + // If the state indicates SPA popup mode, postMessage tokens to the opener and close + state := r.URL.Query().Get("state") + if strings.Contains(state, "mode=spa") { + origin := "" + for _, part := range strings.Split(state, "|") { + if strings.HasPrefix(part, "origin=") { + origin, _ = url.QueryUnescape(strings.TrimPrefix(part, "origin=")) + break + } + } + // fallback: restrict to backend origin if none supplied + if origin == "" { + origin = cfg.OAuthRedirectBase + } + payload := dto.TokenPair{ + AccessToken: access, + RefreshToken: rp.Plain, + TokenType: "Bearer", + ExpiresIn: int64(accessTTL.Seconds()), + } + writePostMessageHTML(w, origin, payload) + return + } + + // Default JSON response + utils.WriteJSON(w, http.StatusOK, dto.TokenPair{ + AccessToken: access, + RefreshToken: rp.Plain, + TokenType: "Bearer", + ExpiresIn: int64(accessTTL.Seconds()), + }) + } +} + +// Refresh godoc +// @ID Refresh +// @Summary Rotate refresh token +// @Tags Auth +// @Accept json +// @Produce json +// @Param body body dto.RefreshRequest true "Refresh token" +// @Success 200 {object} dto.TokenPair +// @Router /auth/refresh [post] +func Refresh(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + cfg, _ := config.Load() + var req dto.RefreshRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, 400, "invalid_json", err.Error()) + return + } + rec, err := auth.ValidateRefreshToken(db, req.RefreshToken) + if err != nil { + utils.WriteError(w, 401, "invalid_refresh", "") + return + } + + var u models.User + if err := db.First(&u, "id = ? AND is_disabled = false", rec.UserID).Error; err != nil { + utils.WriteError(w, 401, "user_disabled", "") + return + } + + // rotate + newPair, err := auth.RotateRefreshToken(db, rec, 30*24*time.Hour) + if err != nil { + utils.WriteError(w, 500, "rotate_failed", err.Error()) + return + } + + // new access + access, err := auth.IssueAccessToken(auth.IssueOpts{ + Subject: u.ID.String(), + Issuer: cfg.JWTIssuer, + Audience: cfg.JWTAudience, + TTL: 1 * time.Hour, + }) + if err != nil { + utils.WriteError(w, 500, "issue_access_failed", err.Error()) + return + } + + utils.WriteJSON(w, 200, dto.TokenPair{ + AccessToken: access, + RefreshToken: newPair.Plain, + TokenType: "Bearer", + ExpiresIn: 3600, + }) + } +} + +// Logout godoc +// @ID Logout +// @Summary Revoke refresh token family (logout everywhere) +// @Tags Auth +// @Accept json +// @Produce json +// @Param body body dto.LogoutRequest true "Refresh token" +// @Success 204 "No Content" +// @Router /auth/logout [post] +func Logout(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req dto.LogoutRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, 400, "invalid_json", err.Error()) + return + } + rec, err := auth.ValidateRefreshToken(db, req.RefreshToken) + if err != nil { + w.WriteHeader(204) // already invalid/revoked + return + } + if err := auth.RevokeFamily(db, rec.FamilyID); err != nil { + utils.WriteError(w, 500, "revoke_failed", err.Error()) + return + } + w.WriteHeader(204) + } +} + +// Helpers + +func upsertAccountAndUser(db *gorm.DB, provider, subject, email, display string) (*models.User, error) { + email = strings.ToLower(email) + var acc models.Account + if err := db.Where("provider = ? AND subject = ?", provider, subject).First(&acc).Error; err == nil { + var u models.User + if err := db.First(&u, "id = ?", acc.UserID).Error; err != nil { + return nil, err + } + return &u, nil + } + // Link by email if exists + var ue models.UserEmail + if err := db.Where("LOWER(email) = ?", email).First(&ue).Error; err == nil { + acc = models.Account{ + UserID: ue.UserID, + Provider: provider, + Subject: subject, + Email: &email, + EmailVerified: true, + } + if err := db.Create(&acc).Error; err != nil { + return nil, err + } + var u models.User + if err := db.First(&u, "id = ?", ue.UserID).Error; err != nil { + return nil, err + } + return &u, nil + } + // Create user + u := models.User{DisplayName: &display, PrimaryEmail: &email} + if err := db.Create(&u).Error; err != nil { + return nil, err + } + ue = models.UserEmail{UserID: u.ID, Email: email, IsVerified: true, IsPrimary: true} + _ = db.Create(&ue).Error + acc = models.Account{UserID: u.ID, Provider: provider, Subject: subject, Email: &email, EmailVerified: true} + _ = db.Create(&acc).Error + return &u, nil +} + +func ensureAutoMembership(db *gorm.DB, userID uuid.UUID, email string) error { + parts := strings.SplitN(strings.ToLower(email), "@", 2) + if len(parts) != 2 { + return nil + } + domain := parts[1] + var org models.Organization + if err := db.Where("LOWER(domain) = ?", domain).First(&org).Error; err != nil { + return nil + } + // if already member, done + var c int64 + db.Model(&models.Membership{}). + Where("user_id = ? AND organization_id = ?", userID, org.ID). + Count(&c) + if c > 0 { + return nil + } + return db.Create(&models.Membership{ + UserID: userID, OrganizationID: org.ID, Role: "member", + }).Error +} + +// writePostMessageHTML sends a tiny HTML page that posts tokens to the SPA and closes the window. +func writePostMessageHTML(w http.ResponseWriter, origin string, payload dto.TokenPair) { + b, _ := json.Marshal(payload) + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Header().Set("Cache-Control", "no-store") + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(``)) +} diff --git a/internal/handlers/dto/auth.go b/internal/handlers/dto/auth.go new file mode 100644 index 0000000..7edc0c9 --- /dev/null +++ b/internal/handlers/dto/auth.go @@ -0,0 +1,24 @@ +package dto + +// swagger:model AuthStartResponse +type AuthStartResponse struct { + AuthURL string `json:"auth_url" example:"https://accounts.google.com/o/oauth2/v2/auth?client_id=..."` +} + +// swagger:model TokenPair +type TokenPair struct { + AccessToken string `json:"access_token" example:"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij..."` + RefreshToken string `json:"refresh_token" example:"m0l9o8rT3t0V8d3eFf...."` + TokenType string `json:"token_type" example:"Bearer"` + ExpiresIn int64 `json:"expires_in" example:"3600"` +} + +// swagger:model RefreshRequest +type RefreshRequest struct { + RefreshToken string `json:"refresh_token" example:"m0l9o8rT3t0V8d3eFf..."` +} + +// swagger:model LogoutRequest +type LogoutRequest struct { + RefreshToken string `json:"refresh_token" example:"m0l9o8rT3t0V8d3eFf..."` +} diff --git a/internal/handlers/dto/jwks.go b/internal/handlers/dto/jwks.go new file mode 100644 index 0000000..d4ddb7e --- /dev/null +++ b/internal/handlers/dto/jwks.go @@ -0,0 +1,19 @@ +package dto + +// JWK represents a single JSON Web Key (public only). +// swagger:model JWK +type JWK struct { + Kty string `json:"kty" example:"RSA" gorm:"-"` + Use string `json:"use,omitempty" example:"sig" gorm:"-"` + Kid string `json:"kid,omitempty" example:"7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345" gorm:"-"` + Alg string `json:"alg,omitempty" example:"RS256" gorm:"-"` + N string `json:"n,omitempty" gorm:"-"` + E string `json:"e,omitempty" example:"AQAB" gorm:"-"` + X string `json:"x,omitempty" gorm:"-"` +} + +// JWKS is a JSON Web Key Set container. +// swagger:model JWKS +type JWKS struct { + Keys []JWK `json:"keys" gorm:"-"` +} diff --git a/internal/handlers/dto/servers.go b/internal/handlers/dto/servers.go new file mode 100644 index 0000000..fabe44f --- /dev/null +++ b/internal/handlers/dto/servers.go @@ -0,0 +1,37 @@ +package dto + +import "github.com/google/uuid" + +type CreateServerRequest struct { + Hostname string `json:"hostname,omitempty"` + PublicIPAddress string `json:"public_ip_address,omitempty"` + PrivateIPAddress string `json:"private_ip_address"` + SSHUser string `json:"ssh_user"` + SshKeyID string `json:"ssh_key_id"` + Role string `json:"role" example:"master|worker|bastion"` + Status string `json:"status,omitempty" example:"pending|provisioning|ready|failed"` +} + +type UpdateServerRequest struct { + Hostname *string `json:"hostname,omitempty"` + PublicIPAddress *string `json:"public_ip_address,omitempty"` + PrivateIPAddress *string `json:"private_ip_address,omitempty"` + SSHUser *string `json:"ssh_user,omitempty"` + SshKeyID *string `json:"ssh_key_id,omitempty"` + Role *string `json:"role,omitempty" example:"master|worker|bastion"` + Status *string `json:"status,omitempty" example:"pending|provisioning|ready|failed"` +} + +type ServerResponse struct { + ID uuid.UUID `json:"id"` + OrganizationID uuid.UUID `json:"organization_id"` + Hostname string `json:"hostname"` + PublicIPAddress *string `json:"public_ip_address,omitempty"` + PrivateIPAddress string `json:"private_ip_address"` + SSHUser string `json:"ssh_user"` + SshKeyID uuid.UUID `json:"ssh_key_id"` + Role string `json:"role"` + Status string `json:"status"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} diff --git a/internal/handlers/dto/ssh.go b/internal/handlers/dto/ssh.go new file mode 100644 index 0000000..e4cb097 --- /dev/null +++ b/internal/handlers/dto/ssh.go @@ -0,0 +1,38 @@ +package dto + +import "github.com/google/uuid" + +type CreateSSHRequest struct { + Name string `json:"name"` + Comment string `json:"comment,omitempty" example:"deploy@autoglue"` + Bits *int `json:"bits,omitempty"` // Only for RSA + Type *string `json:"type,omitempty"` // "rsa" (default) or "ed25519" +} + +type SshResponse struct { + ID uuid.UUID `json:"id"` + OrganizationID uuid.UUID `json:"organization_id"` + Name string `json:"name"` + PublicKey string `json:"public_key"` + Fingerprint string `json:"fingerprint"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +type SshRevealResponse struct { + SshResponse + PrivateKey string `json:"private_key"` +} + +type SshMaterialJSON struct { + ID string `json:"id"` + Name string `json:"name"` + Fingerprint string `json:"fingerprint"` + // Exactly one of the following will be populated for part=public/private. + PublicKey *string `json:"public_key,omitempty"` // OpenSSH authorized_key (string) + PrivatePEM *string `json:"private_pem,omitempty"` // PKCS#1/PEM (string) + // For part=both with mode=json we'll return a base64 zip + ZipBase64 *string `json:"zip_base64,omitempty"` // base64-encoded zip + // Suggested filenames (SDKs can save to disk without inferring names) + Filenames []string `json:"filenames"` +} diff --git a/internal/handlers/dto/taints.go b/internal/handlers/dto/taints.go new file mode 100644 index 0000000..f01690e --- /dev/null +++ b/internal/handlers/dto/taints.go @@ -0,0 +1,22 @@ +package dto + +import "github.com/google/uuid" + +type TaintResponse struct { + ID uuid.UUID `json:"id"` + Key string `json:"key"` + Value string `json:"value"` + Effect string `json:"effect"` +} + +type CreateTaintRequest struct { + Key string `json:"key"` + Value string `json:"value"` + Effect string `json:"effect"` +} + +type UpdateTaintRequest struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` + Effect *string `json:"effect,omitempty"` +} diff --git a/internal/handlers/jwks.go b/internal/handlers/jwks.go new file mode 100644 index 0000000..308b574 --- /dev/null +++ b/internal/handlers/jwks.go @@ -0,0 +1,56 @@ +package handlers + +import ( + "net/http" + + "github.com/glueops/autoglue/internal/auth" + "github.com/glueops/autoglue/internal/handlers/dto" + "github.com/glueops/autoglue/internal/utils" +) + +type jwk struct { + Kty string `json:"kty"` + Use string `json:"use,omitempty"` + Kid string `json:"kid,omitempty"` + Alg string `json:"alg,omitempty"` + N string `json:"n,omitempty"` // RSA modulus (base64url) + E string `json:"e,omitempty"` // RSA exponent (base64url) + X string `json:"x,omitempty"` // Ed25519 public key (base64url) +} + +type jwks struct { + Keys []jwk `json:"keys"` +} + +// JWKSHandler godoc +// @ID getJWKS +// @Summary Get JWKS +// @Description Returns the JSON Web Key Set for token verification +// @Tags Auth +// @Produce json +// @Success 200 {object} dto.JWKS +// @Router /.well-known/jwks.json [get] +func JWKSHandler(w http.ResponseWriter, _ *http.Request) { + out := dto.JWKS{Keys: make([]dto.JWK, 0)} + + auth.KcCopy(func(pub map[string]interface{}) { + for kid, pk := range pub { + meta := auth.MetaFor(kid) + params, kty := auth.PubToJWK(kid, meta.Alg, pk) + if kty == "" { + continue + } + j := dto.JWK{ + Kty: kty, + Use: "sig", + Kid: kid, + Alg: meta.Alg, + N: params["n"], + E: params["e"], + X: params["x"], + } + out.Keys = append(out.Keys, j) + } + }) + utils.WriteJSON(w, http.StatusOK, out) +} diff --git a/internal/handlers/me.go b/internal/handlers/me.go new file mode 100644 index 0000000..e6a9f2e --- /dev/null +++ b/internal/handlers/me.go @@ -0,0 +1,120 @@ +package handlers + +import ( + "encoding/json" + "net/http" + + "github.com/glueops/autoglue/internal/api/httpmiddleware" + "github.com/glueops/autoglue/internal/models" + "github.com/glueops/autoglue/internal/utils" + "gorm.io/gorm" +) + +type meResponse struct { + models.User `json:",inline"` + Emails []models.UserEmail `json:"emails"` + Organizations []models.Organization `json:"organizations"` +} + +// GetMe godoc +// @ID GetMe +// @Summary Get current user profile +// @Tags Me +// @Produce json +// @Success 200 {object} meResponse +// @Router /me [get] +// @Security BearerAuth +// @Security ApiKeyAuth +func GetMe(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := httpmiddleware.UserFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "not signed in") + return + } + + var user models.User + if err := db.First(&user, "id = ? AND is_disabled = false", u.ID).Error; err != nil { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "user not found/disabled") + return + } + + var emails []models.UserEmail + _ = db.Where("user_id = ?", user.ID).Order("is_primary desc, created_at asc").Find(&emails).Error + + var orgs []models.Organization + { + var rows []models.Membership + _ = db.Where("user_id = ?", user.ID).Find(&rows).Error + if len(rows) > 0 { + var ids []interface{} + for _, m := range rows { + ids = append(ids, m.OrganizationID) + } + _ = db.Find(&orgs, "id IN ?", ids).Error + } + } + + utils.WriteJSON(w, http.StatusOK, meResponse{ + User: user, + Emails: emails, + Organizations: orgs, + }) + } +} + +type updateMeRequest struct { + DisplayName *string `json:"display_name,omitempty"` + // You can add more editable fields here (timezone, avatar, etc) +} + +// UpdateMe godoc +// @ID UpdateMe +// @Summary Update current user profile +// @Tags Me +// @Accept json +// @Produce json +// @Param body body updateMeRequest true "Patch profile" +// @Success 200 {object} models.User +// @Router /me [patch] +// @Security BearerAuth +// @Security ApiKeyAuth +func UpdateMe(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := httpmiddleware.UserFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "not signed in") + return + } + + var req updateMeRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, http.StatusBadRequest, "invalid_json", err.Error()) + } + + updates := map[string]interface{}{} + + if req.DisplayName != nil { + updates["display_name"] = req.DisplayName + } + + if len(updates) == 0 { + var user models.User + if err := db.First(&user, "id = ?", u.ID).Error; err != nil { + utils.WriteError(w, 404, "not_found", "user") + return + } + utils.WriteJSON(w, 200, user) + return + } + + if err := db.Model(&models.User{}).Where("id = ?", u.ID).Updates(updates).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + + var out models.User + _ = db.First(&out, "id = ?", u.ID).Error + utils.WriteJSON(w, 200, out) + } +} diff --git a/internal/handlers/me_keys.go b/internal/handlers/me_keys.go new file mode 100644 index 0000000..4dce04f --- /dev/null +++ b/internal/handlers/me_keys.go @@ -0,0 +1,175 @@ +package handlers + +import ( + "crypto/rand" + "encoding/base64" + "encoding/json" + "net/http" + "time" + + "github.com/glueops/autoglue/internal/api/httpmiddleware" + "github.com/glueops/autoglue/internal/auth" + "github.com/glueops/autoglue/internal/models" + "github.com/glueops/autoglue/internal/utils" + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + "gorm.io/gorm" +) + +type userAPIKeyOut struct { + ID uuid.UUID `json:"id" format:"uuid"` + Name *string `json:"name,omitempty"` + Scope string `json:"scope"` // "user" + CreatedAt time.Time `json:"created_at"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + LastUsedAt *time.Time `json:"last_used_at,omitempty"` + Plain *string `json:"plain,omitempty"` // Shown only on create: +} + +// ListUserAPIKeys godoc +// @ID ListUserAPIKeys +// @Summary List my API keys +// @Tags Me / API Keys +// @Produce json +// @Success 200 {array} userAPIKeyOut +// @Router /me/api-keys [get] +// @Security BearerAuth +// @Security ApiKeyAuth +func ListUserAPIKeys(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := httpmiddleware.UserFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "not signed in") + return + } + var rows []models.APIKey + if err := db. + Where("scope = ? AND user_id = ?", "user", u.ID). + Order("created_at desc"). + Find(&rows).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + out := make([]userAPIKeyOut, 0, len(rows)) + for _, k := range rows { + out = append(out, toUserKeyOut(k, nil)) + } + utils.WriteJSON(w, 200, out) + } +} + +type createUserKeyRequest struct { + Name string `json:"name,omitempty"` + ExpiresInHours *int `json:"expires_in_hours,omitempty"` // optional TTL +} + +// CreateUserAPIKey godoc +// @ID CreateUserAPIKey +// @Summary Create a new user API key +// @Description Returns the plaintext key once. Store it securely on the client side. +// @Tags Me / API Keys +// @Accept json +// @Produce json +// @Param body body createUserKeyRequest true "Key options" +// @Success 201 {object} userAPIKeyOut +// @Router /me/api-keys [post] +// @Security BearerAuth +// @Security ApiKeyAuth +func CreateUserAPIKey(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := httpmiddleware.UserFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "not signed in") + return + } + var req createUserKeyRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, 400, "invalid_json", err.Error()) + return + } + + plain, err := generateUserAPIKey() + if err != nil { + utils.WriteError(w, 500, "gen_failed", err.Error()) + return + } + hash := auth.SHA256Hex(plain) + + var exp *time.Time + if req.ExpiresInHours != nil && *req.ExpiresInHours > 0 { + t := time.Now().Add(time.Duration(*req.ExpiresInHours) * time.Hour) + exp = &t + } + + rec := models.APIKey{ + Scope: "user", + UserID: &u.ID, + KeyHash: hash, + Name: req.Name, // if field exists + ExpiresAt: exp, + // SecretHash: nil (not used for user keys) + } + if err := db.Create(&rec).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + utils.WriteJSON(w, http.StatusCreated, toUserKeyOut(rec, &plain)) + } +} + +// DeleteUserAPIKey godoc +// @ID DeleteUserAPIKey +// @Summary Delete a user API key +// @Tags Me / API Keys +// @Produce json +// @Param id path string true "Key ID (UUID)" +// @Success 204 "No Content" +// @Router /me/api-keys/{id} [delete] +// @Security BearerAuth +func DeleteUserAPIKey(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := httpmiddleware.UserFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "not signed in") + return + } + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, 400, "invalid_id", "must be uuid") + return + } + tx := db.Where("id = ? AND scope = ? AND user_id = ?", id, "user", u.ID). + Delete(&models.APIKey{}) + if tx.Error != nil { + utils.WriteError(w, 500, "db_error", tx.Error.Error()) + return + } + if tx.RowsAffected == 0 { + utils.WriteError(w, 404, "not_found", "key not found") + return + } + w.WriteHeader(http.StatusNoContent) + } +} + +func toUserKeyOut(k models.APIKey, plain *string) userAPIKeyOut { + return userAPIKeyOut{ + ID: k.ID, + Name: &k.Name, // if your model has it; else remove + Scope: k.Scope, + CreatedAt: k.CreatedAt, + ExpiresAt: k.ExpiresAt, + LastUsedAt: k.LastUsedAt, // if present; else remove + Plain: plain, + } +} + +func generateUserAPIKey() (string, error) { + // 24 random bytes → base64url (no padding), with "u_" prefix + b := make([]byte, 24) + if _, err := rand.Read(b); err != nil { + return "", err + } + s := base64.RawURLEncoding.EncodeToString(b) + return "u_" + s, nil +} diff --git a/internal/handlers/orgs.go b/internal/handlers/orgs.go new file mode 100644 index 0000000..d8f0ace --- /dev/null +++ b/internal/handlers/orgs.go @@ -0,0 +1,647 @@ +package handlers + +import ( + "crypto/rand" + "encoding/base64" + "encoding/json" + "errors" + "net/http" + "strings" + "time" + + "github.com/glueops/autoglue/internal/api/httpmiddleware" + "github.com/glueops/autoglue/internal/auth" + "github.com/glueops/autoglue/internal/models" + "github.com/glueops/autoglue/internal/utils" + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + "gorm.io/gorm" +) + +// ---------- Helpers ---------- + +func mustUser(r *http.Request) (*models.User, bool) { + return httpmiddleware.UserFrom(r.Context()) +} + +func isOrgRole(db *gorm.DB, userID, orgID uuid.UUID, want ...string) (bool, string) { + var m models.Membership + if err := db.Where("user_id = ? AND organization_id = ?", userID, orgID).First(&m).Error; err != nil { + return false, "" + } + got := strings.ToLower(m.Role) + for _, w := range want { + if got == strings.ToLower(w) { + return true, got + } + } + return false, got +} + +func mustMember(db *gorm.DB, userID, orgID uuid.UUID) bool { + ok, _ := isOrgRole(db, userID, orgID, "owner", "admin", "member") + return ok +} + +func randomB64URL(n int) (string, error) { + b := make([]byte, n) + if _, err := rand.Read(b); err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(b), nil +} + +// ---------- Orgs: list/create/get/update/delete ---------- + +type orgCreateReq struct { + Name string `json:"name" example:"Acme Corp"` + Domain *string `json:"domain,omitempty" example:"acme.com"` +} + +// CreateOrg godoc +// @ID CreateOrg +// @Summary Create organization +// @Tags Orgs +// @Accept json +// @Produce json +// @Param body body orgCreateReq true "Org payload" +// @Success 201 {object} models.Organization +// @Failure 400 {object} utils.ErrorResponse +// @Failure 401 {object} utils.ErrorResponse +// @Failure 409 {object} utils.ErrorResponse +// @Router /orgs [post] +// @ID createOrg +// @Security BearerAuth +func CreateOrg(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "") + return + } + + var req orgCreateReq + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, 400, "invalid_json", err.Error()) + return + } + + if strings.TrimSpace(req.Name) == "" { + utils.WriteError(w, 400, "validation_error", "name is required") + return + } + + org := models.Organization{Name: req.Name} + if req.Domain != nil && strings.TrimSpace(*req.Domain) != "" { + org.Domain = req.Domain + } + + if err := db.Create(&org).Error; err != nil { + utils.WriteError(w, 409, "conflict", err.Error()) + return + } + + // creator is owner + _ = db.Create(&models.Membership{ + UserID: u.ID, OrganizationID: org.ID, Role: "owner", + }).Error + + utils.WriteJSON(w, 201, org) + } +} + +// ListMyOrgs godoc +// @ID ListMyOrgs +// @Summary List organizations I belong to +// @Tags Orgs +// @Produce json +// @Success 200 {array} models.Organization +// @Failure 401 {object} utils.ErrorResponse +// @Router /orgs [get] +// @ID listMyOrgs +// @Security BearerAuth +func ListMyOrgs(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, http.StatusUnauthorized, "unauthorized", "") + return + } + + var orgs []models.Organization + if err := db. + Joins("join memberships m on m.organization_id = organizations.id"). + Where("m.user_id = ?", u.ID). + Order("organizations.created_at desc"). + Find(&orgs).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + utils.WriteJSON(w, 200, orgs) + } +} + +// GetOrg godoc +// @ID GetOrg +// @Summary Get organization +// @Tags Orgs +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Success 200 {object} models.Organization +// @Failure 401 {object} utils.ErrorResponse +// @Failure 404 {object} utils.ErrorResponse +// @Router /orgs/{id} [get] +// @ID getOrg +// @Security BearerAuth +func GetOrg(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + if !mustMember(db, u.ID, oid) { + utils.WriteError(w, 401, "forbidden", "not a member") + return + } + var org models.Organization + if err := db.First(&org, "id = ?", oid).Error; err != nil { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + utils.WriteJSON(w, 200, org) + } +} + +type orgUpdateReq struct { + Name *string `json:"name,omitempty"` + Domain *string `json:"domain,omitempty"` +} + +// UpdateOrg godoc +// @ID UpdateOrg +// @Summary Update organization (owner/admin) +// @Tags Orgs +// @Accept json +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Param body body orgUpdateReq true "Update payload" +// @Success 200 {object} models.Organization +// @Failure 401 {object} utils.ErrorResponse +// @Failure 404 {object} utils.ErrorResponse +// @Router /orgs/{id} [patch] +// @ID updateOrg +// @Security BearerAuth +func UpdateOrg(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + if ok, _ := isOrgRole(db, u.ID, oid, "owner", "admin"); !ok { + utils.WriteError(w, 401, "forbidden", "admin or owner required") + return + } + var req orgUpdateReq + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, 400, "invalid_json", err.Error()) + return + } + changes := map[string]any{} + if req.Name != nil { + changes["name"] = strings.TrimSpace(*req.Name) + } + if req.Domain != nil { + if d := strings.TrimSpace(*req.Domain); d == "" { + changes["domain"] = nil + } else { + changes["domain"] = d + } + } + if len(changes) > 0 { + if err := db.Model(&models.Organization{}).Where("id = ?", oid).Updates(changes).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + } + var out models.Organization + _ = db.First(&out, "id = ?", oid).Error + utils.WriteJSON(w, 200, out) + } +} + +// DeleteOrg godoc +// @ID DeleteOrg +// @Summary Delete organization (owner) +// @Tags Orgs +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Success 204 "Deleted" +// @Failure 401 {object} utils.ErrorResponse +// @Failure 404 {object} utils.ErrorResponse +// @Router /orgs/{id} [delete] +// @ID deleteOrg +// @Security BearerAuth +func DeleteOrg(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + if ok, _ := isOrgRole(db, u.ID, oid, "owner"); !ok { + utils.WriteError(w, 401, "forbidden", "owner required") + return + } + // Optional safety: deny if members >1 or resources exist; here we just delete. + res := db.Delete(&models.Organization{}, "id = ?", oid) + if res.Error != nil { + utils.WriteError(w, 500, "db_error", res.Error.Error()) + return + } + if res.RowsAffected == 0 { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + w.WriteHeader(204) + } +} + +// ---------- Members: list/add/update/delete ---------- + +type memberOut struct { + UserID uuid.UUID `json:"user_id" format:"uuid"` + Email string `json:"email"` + Role string `json:"role"` // owner/admin/member +} + +type memberUpsertReq struct { + UserID uuid.UUID `json:"user_id" format:"uuid"` + Role string `json:"role" example:"member"` +} + +// ListMembers godoc +// @ID ListMembers +// @Summary List members in org +// @Tags Orgs +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Success 200 {array} memberOut +// @Failure 401 {object} utils.ErrorResponse +// @Router /orgs/{id}/members [get] +// @ID listMembers +// @Security BearerAuth +func ListMembers(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil || !mustMember(db, u.ID, oid) { + utils.WriteError(w, 401, "forbidden", "") + return + } + var ms []models.Membership + if err := db.Where("organization_id = ?", oid).Find(&ms).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + + // load emails + userIDs := make([]uuid.UUID, 0, len(ms)) + for _, m := range ms { + userIDs = append(userIDs, m.UserID) + } + var emails []models.UserEmail + if len(userIDs) > 0 { + _ = db.Where("user_id in ?", userIDs).Where("is_primary = true").Find(&emails).Error + } + emailByUser := map[uuid.UUID]string{} + for _, e := range emails { + emailByUser[e.UserID] = e.Email + } + + out := make([]memberOut, 0, len(ms)) + for _, m := range ms { + out = append(out, memberOut{ + UserID: m.UserID, + Email: emailByUser[m.UserID], + Role: m.Role, + }) + } + utils.WriteJSON(w, 200, out) + } +} + +// AddOrUpdateMember godoc +// @ID AddOrUpdateMember +// @Summary Add or update a member (owner/admin) +// @Tags Orgs +// @Accept json +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Param body body memberUpsertReq true "User & role" +// @Success 200 {object} memberOut +// @Failure 401 {object} utils.ErrorResponse +// @Router /orgs/{id}/members [post] +// @ID addOrUpdateMember +// @Security BearerAuth +func AddOrUpdateMember(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + if ok, _ := isOrgRole(db, u.ID, oid, "owner", "admin"); !ok { + utils.WriteError(w, 401, "forbidden", "admin or owner required") + return + } + var req memberUpsertReq + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, 400, "invalid_json", err.Error()) + return + } + role := strings.ToLower(strings.TrimSpace(req.Role)) + if role != "owner" && role != "admin" && role != "member" { + utils.WriteError(w, 400, "validation_error", "role must be owner|admin|member") + return + } + var m models.Membership + tx := db.Where("user_id = ? AND organization_id = ?", req.UserID, oid).First(&m) + if tx.Error == nil { + // update + if err := db.Model(&m).Update("role", role).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + } else if errors.Is(tx.Error, gorm.ErrRecordNotFound) { + m = models.Membership{UserID: req.UserID, OrganizationID: oid, Role: role} + if err := db.Create(&m).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + } else { + utils.WriteError(w, 500, "db_error", tx.Error.Error()) + return + } + + // make response + var ue models.UserEmail + _ = db.Where("user_id = ? AND is_primary = true", req.UserID).First(&ue).Error + utils.WriteJSON(w, 200, memberOut{ + UserID: req.UserID, Email: ue.Email, Role: m.Role, + }) + } +} + +// RemoveMember godoc +// @ID RemoveMember +// @Summary Remove a member (owner/admin) +// @Tags Orgs +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Param user_id path string true "User ID (UUID)" +// @Success 204 "Removed" +// @Failure 401 {object} utils.ErrorResponse +// @Router /orgs/{id}/members/{user_id} [delete] +// @ID removeMember +// @Security BearerAuth +func RemoveMember(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + if ok, _ := isOrgRole(db, u.ID, oid, "owner", "admin"); !ok { + utils.WriteError(w, 401, "forbidden", "admin or owner required") + return + } + uid, err := uuid.Parse(chi.URLParam(r, "user_id")) + if err != nil { + utils.WriteError(w, 400, "invalid_user_id", "") + return + } + res := db.Where("user_id = ? AND organization_id = ?", uid, oid).Delete(&models.Membership{}) + if res.Error != nil { + utils.WriteError(w, 500, "db_error", res.Error.Error()) + return + } + w.WriteHeader(204) + } +} + +// ---------- Org API Keys (key/secret pair) ---------- + +type orgKeyCreateReq struct { + Name string `json:"name,omitempty" example:"automation-bot"` + ExpiresInHours *int `json:"expires_in_hours,omitempty" example:"720"` +} + +type orgKeyCreateResp struct { + ID uuid.UUID `json:"id"` + Name string `json:"name,omitempty"` + Scope string `json:"scope"` // "org" + CreatedAt time.Time `json:"created_at"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + OrgKey string `json:"org_key"` // shown once: + OrgSecret string `json:"org_secret"` // shown once: +} + +// ListOrgKeys godoc +// @ID ListOrgKeys +// @Summary List org-scoped API keys (no secrets) +// @Tags Orgs +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Success 200 {array} models.APIKey +// @Failure 401 {object} utils.ErrorResponse +// @Router /orgs/{id}/api-keys [get] +// @ID listOrgKeys +// @Security BearerAuth +func ListOrgKeys(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil || !mustMember(db, u.ID, oid) { + utils.WriteError(w, 401, "forbidden", "") + return + } + var keys []models.APIKey + if err := db.Where("org_id = ? AND scope = ?", oid, "org"). + Order("created_at desc"). + Find(&keys).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + // SecretHash must not be exposed; your json tags likely hide it already. + utils.WriteJSON(w, 200, keys) + } +} + +// CreateOrgKey godoc +// @ID CreateOrgKey +// @Summary Create org key/secret pair (owner/admin) +// @Tags Orgs +// @Accept json +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Param body body orgKeyCreateReq true "Key name + optional expiry" +// @Success 201 {object} orgKeyCreateResp +// @Failure 401 {object} utils.ErrorResponse +// @Router /orgs/{id}/api-keys [post] +// @ID createOrgKey +// @Security BearerAuth +func CreateOrgKey(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + if ok, _ := isOrgRole(db, u.ID, oid, "owner", "admin"); !ok { + utils.WriteError(w, 401, "forbidden", "admin or owner required") + return + } + + var req orgKeyCreateReq + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, 400, "invalid_json", err.Error()) + return + } + + // generate + keySuffix, err := randomB64URL(16) + if err != nil { + utils.WriteError(w, 500, "entropy_error", err.Error()) + return + } + sec, err := randomB64URL(32) + if err != nil { + utils.WriteError(w, 500, "entropy_error", err.Error()) + return + } + orgKey := "org_" + keySuffix + secretPlain := sec + + keyHash := auth.SHA256Hex(orgKey) + secretHash, err := auth.HashSecretArgon2id(secretPlain) + if err != nil { + utils.WriteError(w, 500, "hash_error", err.Error()) + return + } + + var exp *time.Time + if req.ExpiresInHours != nil && *req.ExpiresInHours > 0 { + e := time.Now().Add(time.Duration(*req.ExpiresInHours) * time.Hour) + exp = &e + } + + rec := models.APIKey{ + OrgID: &oid, + Scope: "org", + Name: req.Name, + KeyHash: keyHash, + SecretHash: &secretHash, + ExpiresAt: exp, + } + if err := db.Create(&rec).Error; err != nil { + utils.WriteError(w, 500, "db_error", err.Error()) + return + } + + utils.WriteJSON(w, 201, orgKeyCreateResp{ + ID: rec.ID, + Name: rec.Name, + Scope: rec.Scope, + CreatedAt: rec.CreatedAt, + ExpiresAt: rec.ExpiresAt, + OrgKey: orgKey, + OrgSecret: secretPlain, + }) + } +} + +// DeleteOrgKey godoc +// @ID DeleteOrgKey +// @Summary Delete org key (owner/admin) +// @Tags Orgs +// @Produce json +// @Param id path string true "Org ID (UUID)" +// @Param key_id path string true "Key ID (UUID)" +// @Success 204 "Deleted" +// @Failure 401 {object} utils.ErrorResponse +// @Router /orgs/{id}/api-keys/{key_id} [delete] +// @ID deleteOrgKey +// @Security BearerAuth +func DeleteOrgKey(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + u, ok := mustUser(r) + if !ok { + utils.WriteError(w, 401, "unauthorized", "") + return + } + oid, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, 404, "not_found", "org not found") + return + } + if ok, _ := isOrgRole(db, u.ID, oid, "owner", "admin"); !ok { + utils.WriteError(w, 401, "forbidden", "admin or owner required") + return + } + kid, err := uuid.Parse(chi.URLParam(r, "key_id")) + if err != nil { + utils.WriteError(w, 400, "invalid_key_id", "") + return + } + res := db.Where("id = ? AND org_id = ? AND scope = ?", kid, oid, "org").Delete(&models.APIKey{}) + if res.Error != nil { + utils.WriteError(w, 500, "db_error", res.Error.Error()) + return + } + if res.RowsAffected == 0 { + utils.WriteError(w, 404, "not_found", "key not found") + return + } + w.WriteHeader(204) + } +} diff --git a/internal/handlers/servers.go b/internal/handlers/servers.go new file mode 100644 index 0000000..97e5fc9 --- /dev/null +++ b/internal/handlers/servers.go @@ -0,0 +1,388 @@ +package handlers + +import ( + "encoding/json" + "errors" + "net/http" + "strings" + "time" + + "github.com/glueops/autoglue/internal/api/httpmiddleware" + "github.com/glueops/autoglue/internal/handlers/dto" + "github.com/glueops/autoglue/internal/models" + "github.com/glueops/autoglue/internal/utils" + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + "gorm.io/gorm" +) + +// ListServers godoc +// @ID ListServers +// @Summary List servers (org scoped) +// @Description Returns servers for the organization in X-Org-ID. Optional filters: status, role. +// @Tags Servers +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param status query string false "Filter by status (pending|provisioning|ready|failed)" +// @Param role query string false "Filter by role" +// @Success 200 {array} dto.ServerResponse +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "failed to list servers" +// @Router /servers [get] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func ListServers(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + q := db.Where("organization_id = ?", orgID) + + if s := strings.TrimSpace(r.URL.Query().Get("status")); s != "" { + if !validStatus(s) { + utils.WriteError(w, http.StatusBadRequest, "status_invalid", "invalid status") + return + } + q = q.Where("status = ?", strings.ToLower(s)) + } + + if role := strings.TrimSpace(r.URL.Query().Get("role")); role != "" { + q = q.Where("role = ?", role) + } + + var rows []models.Server + if err := q.Order("created_at DESC").Find(&rows).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to list servers") + return + } + + out := make([]dto.ServerResponse, 0, len(rows)) + for _, row := range rows { + out = append(out, dto.ServerResponse{ + ID: row.ID, + OrganizationID: row.OrganizationID, + Hostname: row.Hostname, + PublicIPAddress: row.PublicIPAddress, + PrivateIPAddress: row.PrivateIPAddress, + SSHUser: row.SSHUser, + SshKeyID: row.SshKeyID, + Role: row.Role, + Status: row.Status, + CreatedAt: row.CreatedAt.UTC().Format(time.RFC3339), + UpdatedAt: row.UpdatedAt.UTC().Format(time.RFC3339), + }) + } + utils.WriteJSON(w, http.StatusOK, out) + } +} + +// GetServer godoc +// @ID GetServer +// @Summary Get server by ID (org scoped) +// @Description Returns one server in the given organization. +// @Tags Servers +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param id path string true "Server ID (UUID)" +// @Success 200 {object} dto.ServerResponse +// @Failure 400 {string} string "invalid id" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 404 {string} string "not found" +// @Failure 500 {string} string "fetch failed" +// @Router /servers/{id} [get] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func GetServer(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "id_invalid", "invalid id") + return + } + + var row models.Server + if err := db.Where("id = ? AND organization_id = ?", id, orgID).First(&row).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + utils.WriteError(w, http.StatusNotFound, "server_not_found", "server not found") + return + } + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to get server") + return + } + + utils.WriteJSON(w, http.StatusOK, row) + } +} + +// CreateServer godoc +// @ID CreateServer +// @Summary Create server (org scoped) +// @Description Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org. +// @Tags Servers +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param body body dto.CreateServerRequest true "Server payload" +// @Success 201 {object} dto.ServerResponse +// @Failure 400 {string} string "invalid json / missing fields / invalid status / invalid ssh_key_id" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "create failed" +// @Router /servers [post] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func CreateServer(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + var req dto.CreateServerRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "bad request") + return + } + + req.Role = strings.ToLower(strings.TrimSpace(req.Role)) + req.Status = strings.ToLower(strings.TrimSpace(req.Status)) + pub := strings.TrimSpace(req.PublicIPAddress) + + if req.PrivateIPAddress == "" || req.SSHUser == "" || req.SshKeyID == "" || req.Role == "" { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "private_ip_address, ssh_user, ssh_key_id and role are required") + return + } + + if req.Status != "" && !validStatus(req.Status) { + utils.WriteError(w, http.StatusBadRequest, "status_invalid", "invalid status") + return + } + + if req.Role == "bastion" && pub == "" { + utils.WriteError(w, http.StatusBadRequest, "public_ip_required", "public_ip_address is required for role=bastion") + return + } + + keyID, err := uuid.Parse(req.SshKeyID) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "invalid ssh_key_id") + return + } + if err := ensureKeyBelongsToOrg(orgID, keyID, db); err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "invalid or unauthorized ssh_key_id") + return + } + + var publicPtr *string + if pub != "" { + publicPtr = &pub + } + + s := models.Server{ + OrganizationID: orgID, + Hostname: req.Hostname, + PublicIPAddress: publicPtr, + PrivateIPAddress: req.PrivateIPAddress, + SSHUser: req.SSHUser, + SshKeyID: keyID, + Role: req.Role, + Status: "pending", + } + if req.Status != "" { + s.Status = strings.ToLower(req.Status) + } + + if err := db.Create(&s).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to create server") + return + } + utils.WriteJSON(w, http.StatusCreated, s) + } +} + +// UpdateServer godoc +// @ID UpdateServer +// @Summary Update server (org scoped) +// @Description Partially update fields; changing ssh_key_id validates ownership. +// @Tags Servers +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param id path string true "Server ID (UUID)" +// @Param body body dto.UpdateServerRequest true "Fields to update" +// @Success 200 {object} dto.ServerResponse +// @Failure 400 {string} string "invalid id / invalid json / invalid status / invalid ssh_key_id" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 404 {string} string "not found" +// @Failure 500 {string} string "update failed" +// @Router /servers/{id} [patch] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func UpdateServer(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "id_invalid", "invalid id") + return + } + + var server models.Server + if err := db.Where("id = ? AND organization_id = ?", id, orgID).First(&server).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + utils.WriteError(w, http.StatusNotFound, "server_not_found", "server not found") + return + } + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to get server") + return + } + + var req dto.UpdateServerRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "bad request") + return + } + + next := server + + if req.Hostname != nil { + next.Hostname = *req.Hostname + } + if req.PrivateIPAddress != nil { + next.PrivateIPAddress = *req.PrivateIPAddress + } + if req.PublicIPAddress != nil { + next.PublicIPAddress = req.PublicIPAddress + } + if req.SSHUser != nil { + next.SSHUser = *req.SSHUser + } + if req.Role != nil { + next.Role = *req.Role + } + if req.Status != nil { + st := strings.ToLower(strings.TrimSpace(*req.Status)) + if !validStatus(st) { + utils.WriteError(w, http.StatusBadRequest, "status_invalid", "invalid status") + return + } + next.Status = st + } + if req.SshKeyID != nil { + keyID, err := uuid.Parse(*req.SshKeyID) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "invalid ssh_key_id") + return + } + if err := ensureKeyBelongsToOrg(orgID, keyID, db); err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "invalid or unauthorized ssh_key_id") + return + } + next.SshKeyID = keyID + } + + if strings.EqualFold(next.Role, "bastion") && + (next.PublicIPAddress == nil || strings.TrimSpace(*next.PublicIPAddress) == "") { + utils.WriteError(w, http.StatusBadRequest, "public_ip_required", "public_ip_address is required for role=bastion") + return + } + + if err := db.Save(&next).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to update server") + return + } + utils.WriteJSON(w, http.StatusOK, server) + } +} + +// DeleteServer godoc +// @ID DeleteServer +// @Summary Delete server (org scoped) +// @Description Permanently deletes the server. +// @Tags Servers +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param id path string true "Server ID (UUID)" +// @Success 204 {string} string "No Content" +// @Failure 400 {string} string "invalid id" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "delete failed" +// @Router /servers/{id} [delete] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func DeleteServer(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "id_invalid", "invalid id") + return + } + + if err := db.Where("id = ? AND organization_id = ?", id, orgID).First(&models.Server{}).Error; err != nil { + utils.WriteError(w, http.StatusNotFound, "server_not_found", "server not found") + return + } + + if err := db.Where("id = ? AND organization_id = ?", id, orgID).Delete(&models.Server{}).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to delete server") + return + } + + w.WriteHeader(http.StatusNoContent) + } +} + +// --- Helpers --- + +func validStatus(status string) bool { + switch strings.ToLower(status) { + case "pending", "provisioning", "ready", "failed", "": + return true + default: + return false + } +} + +func ensureKeyBelongsToOrg(orgID, keyID uuid.UUID, db *gorm.DB) error { + var k models.SshKey + if err := db.Where("id = ? AND organization_id = ?", keyID, orgID).First(&k).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return errors.New("ssh key not found for this organization") + } + return err + } + return nil +} diff --git a/internal/handlers/ssh.go b/internal/handlers/ssh.go new file mode 100644 index 0000000..2d590ca --- /dev/null +++ b/internal/handlers/ssh.go @@ -0,0 +1,553 @@ +package handlers + +import ( + "archive/zip" + "bytes" + "crypto/ed25519" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/glueops/autoglue/internal/api/httpmiddleware" + "github.com/glueops/autoglue/internal/handlers/dto" + "github.com/glueops/autoglue/internal/models" + "github.com/glueops/autoglue/internal/utils" + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + "golang.org/x/crypto/ssh" + "gorm.io/gorm" +) + +// ListPublicSshKeys godoc +// @ID ListPublicSshKeys +// @Summary List ssh keys (org scoped) +// @Description Returns ssh keys for the organization in X-Org-ID. +// @Tags Ssh +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Success 200 {array} dto.SshResponse +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "failed to list keys" +// @Router /ssh [get] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func ListPublicSshKeys(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + var rows []models.SshKey + if err := db.Where("organization_id = ?", orgID).Order("created_at DESC").Find(&rows).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to list ssh keys") + return + } + + out := make([]dto.SshResponse, 0, len(rows)) + for _, row := range rows { + out = append(out, dto.SshResponse{ + ID: row.ID, + OrganizationID: row.OrganizationID, + Name: row.Name, + PublicKey: row.PublicKey, + Fingerprint: row.Fingerprint, + CreatedAt: row.CreatedAt.UTC().Format(time.RFC3339), + UpdatedAt: row.UpdatedAt.UTC().Format(time.RFC3339), + }) + } + + utils.WriteJSON(w, http.StatusOK, out) + } +} + +// CreateSSHKey +// @ID CreateSSHKey +// @Summary Create ssh keypair (org scoped) +// @Description Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits. +// @Tags Ssh +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param body body dto.CreateSSHRequest true "Key generation options" +// @Success 201 {object} dto.SshResponse +// @Failure 400 {string} string "invalid json / invalid bits" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "generation/create failed" +// @Router /ssh [post] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func CreateSSHKey(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + var req dto.CreateSSHRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, http.StatusBadRequest, "invalid_payload", "invalid JSON payload") + return + } + + keyType := "rsa" + if req.Type != nil && strings.TrimSpace(*req.Type) != "" { + keyType = strings.ToLower(strings.TrimSpace(*req.Type)) + } + + if keyType != "rsa" && keyType != "ed25519" { + utils.WriteError(w, http.StatusBadRequest, "invalid_type", "invalid type (rsa|ed25519)") + return + } + + var ( + privPEM string + pubAuth string + err error + ) + + switch keyType { + case "rsa": + bits := 4096 + if req.Bits != nil { + if !allowedBits(*req.Bits) { + utils.WriteError(w, http.StatusBadRequest, "invalid_bits", "invalid bits (allowed: 2048, 3072, 4096)") + return + } + bits = *req.Bits + } + privPEM, pubAuth, err = GenerateRSAPEMAndAuthorized(bits, strings.TrimSpace(req.Comment)) + + case "ed25519": + if req.Bits != nil { + utils.WriteError(w, http.StatusBadRequest, "invalid_bits_for_type", "bits is only valid for RSA") + return + } + privPEM, pubAuth, err = GenerateEd25519PEMAndAuthorized(strings.TrimSpace(req.Comment)) + } + + if err != nil { + utils.WriteError(w, http.StatusInternalServerError, "keygen_failure", "key generation failed") + return + } + + cipher, iv, tag, err := utils.EncryptForOrg(orgID, []byte(privPEM), db) + if err != nil { + http.Error(w, "encryption failed", http.StatusInternalServerError) + return + } + + parsed, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubAuth)) + if err != nil { + utils.WriteError(w, http.StatusInternalServerError, "ssh_failure", "ssh public key parsing failed") + return + } + + fp := ssh.FingerprintSHA256(parsed) + + key := models.SshKey{ + OrganizationID: orgID, + Name: req.Name, + PublicKey: pubAuth, + EncryptedPrivateKey: cipher, + PrivateIV: iv, + PrivateTag: tag, + Fingerprint: fp, + } + + if err := db.Create(&key).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to create ssh key") + return + } + + utils.WriteJSON(w, http.StatusCreated, dto.SshResponse{ + ID: key.ID, + OrganizationID: key.OrganizationID, + Name: key.Name, + PublicKey: key.PublicKey, + Fingerprint: key.Fingerprint, + CreatedAt: key.CreatedAt.UTC().Format(time.RFC3339), + UpdatedAt: key.UpdatedAt.UTC().Format(time.RFC3339), + }) + } +} + +// GetSSHKey godoc +// @ID GetSSHKey +// @Summary Get ssh key by ID (org scoped) +// @Description Returns public key fields. Append `?reveal=true` to include the private key PEM. +// @Tags Ssh +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param id path string true "SSH Key ID (UUID)" +// @Param reveal query bool false "Reveal private key PEM" +// @Success 200 {object} dto.SshResponse +// @Success 200 {object} dto.SshRevealResponse "When reveal=true" +// @Failure 400 {string} string "invalid id" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 404 {string} string "not found" +// @Failure 500 {string} string "fetch failed" +// @Router /ssh/{id} [get] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func GetSSHKey(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "invalid_ssh_key_id", "invalid SSH Key ID") + return + } + + var key models.SshKey + if err := db.Where("id = ? AND organization_id = ?", id, orgID).First(&key).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + utils.WriteError(w, http.StatusNotFound, "ssh_key_not_found", "ssh key not found") + return + } + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to get ssh key") + return + } + + if r.URL.Query().Get("reveal") != "true" { + utils.WriteJSON(w, http.StatusOK, dto.SshResponse{ + ID: key.ID, + OrganizationID: key.OrganizationID, + Name: key.Name, + PublicKey: key.PublicKey, + Fingerprint: key.Fingerprint, + CreatedAt: key.CreatedAt.UTC().Format(time.RFC3339), + UpdatedAt: key.UpdatedAt.UTC().Format(time.RFC3339), + }) + return + } + + plain, err := utils.DecryptForOrg(orgID, key.EncryptedPrivateKey, key.PrivateIV, key.PrivateTag, db) + if err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to decrypt ssh key") + return + } + + utils.WriteJSON(w, http.StatusOK, dto.SshRevealResponse{ + SshResponse: dto.SshResponse{ + ID: key.ID, + OrganizationID: key.OrganizationID, + Name: key.Name, + PublicKey: key.PublicKey, + Fingerprint: key.Fingerprint, + CreatedAt: key.CreatedAt.UTC().Format(time.RFC3339), + UpdatedAt: key.UpdatedAt.UTC().Format(time.RFC3339), + }, + PrivateKey: plain, + }) + } +} + +// DeleteSSHKey godoc +// @ID DeleteSSHKey +// @Summary Delete ssh keypair (org scoped) +// @Description Permanently deletes a keypair. +// @Tags Ssh +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param id path string true "SSH Key ID (UUID)" +// @Success 204 {string} string "No Content" +// @Failure 400 {string} string "invalid id" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "delete failed" +// @Router /ssh/{id} [delete] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func DeleteSSHKey(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "invalid_ssh_key_id", "invalid SSH Key ID") + return + } + + if err := db.Where("id = ? AND organization_id = ?", id, orgID). + Delete(&models.SshKey{}).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to delete ssh key") + return + } + w.WriteHeader(http.StatusNoContent) + } +} + +// DownloadSSHKey godoc +// @ID DownloadSSHKey +// @Summary Download ssh key files by ID (org scoped) +// @Description Download `part=public|private|both` of the keypair. `both` returns a zip file. +// @Tags Ssh +// @Produce json +// @Param X-Org-ID header string true "Organization UUID" +// @Param id path string true "SSH Key ID (UUID)" +// @Param part query string true "Which part to download" Enums(public,private,both) +// @Success 200 {string} string "file content" +// @Failure 400 {string} string "invalid id / invalid part" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 404 {string} string "not found" +// @Failure 500 {string} string "download failed" +// @Router /ssh/{id}/download [get] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func DownloadSSHKey(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "invalid_ssh_key_id", "invalid SSH Key ID") + return + } + + var key models.SshKey + if err := db.Where("id = ? AND organization_id = ?", id, orgID). + First(&key).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + utils.WriteError(w, http.StatusNotFound, "ssh_key_not_found", "ssh key not found") + return + } + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to get ssh key") + return + } + + part := strings.ToLower(r.URL.Query().Get("part")) + if part == "" { + utils.WriteError(w, http.StatusBadRequest, "invalid_ssh_part", "invalid part (public|private|both)") + return + } + + mode := strings.ToLower(r.URL.Query().Get("mode")) + if mode != "" && mode != "json" { + utils.WriteError(w, http.StatusBadRequest, "invalid_mode", "invalid mode (json|attachment[default])") + return + } + + if mode == "json" { + resp := dto.SshMaterialJSON{ + ID: key.ID.String(), + Name: key.Name, + Fingerprint: key.Fingerprint, + } + switch part { + case "public": + pub := key.PublicKey + resp.PublicKey = &pub + resp.Filenames = []string{fmt.Sprintf("id_rsa_%s.pub", key.ID.String())} + utils.WriteJSON(w, http.StatusOK, resp) + return + + case "private": + plain, err := utils.DecryptForOrg(orgID, key.EncryptedPrivateKey, key.PrivateIV, key.PrivateTag, db) + if err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to decrypt ssh key") + return + } + resp.PrivatePEM = &plain + resp.Filenames = []string{fmt.Sprintf("id_rsa_%s.pem", key.ID.String())} + utils.WriteJSON(w, http.StatusOK, resp) + return + + case "both": + plain, err := utils.DecryptForOrg(orgID, key.EncryptedPrivateKey, key.PrivateIV, key.PrivateTag, db) + if err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to decrypt ssh key") + return + } + + var buf bytes.Buffer + zw := zip.NewWriter(&buf) + _ = toZipFile(fmt.Sprintf("id_rsa_%s.pem", key.ID.String()), []byte(plain), zw) + _ = toZipFile(fmt.Sprintf("id_rsa_%s.pub", key.ID.String()), []byte(key.PublicKey), zw) + _ = zw.Close() + + b64 := utils.EncodeB64(buf.Bytes()) + resp.ZipBase64 = &b64 + resp.Filenames = []string{ + fmt.Sprintf("id_rsa_%s.zip", key.ID.String()), + fmt.Sprintf("id_rsa_%s.pem", key.ID.String()), + fmt.Sprintf("id_rsa_%s.pub", key.ID.String()), + } + utils.WriteJSON(w, http.StatusOK, resp) + return + + default: + utils.WriteError(w, http.StatusBadRequest, "invalid_ssh_part", "invalid part (public|private|both)") + return + } + } + + prefix := keyFilenamePrefix(key.PublicKey) + + switch part { + case "public": + filename := fmt.Sprintf("%s_%s.pub", prefix, key.ID.String()) + w.Header().Set("Content-Type", "text/plain") + w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename)) + _, _ = w.Write([]byte(key.PublicKey)) + return + + case "private": + plain, err := utils.DecryptForOrg(orgID, key.EncryptedPrivateKey, key.PrivateIV, key.PrivateTag, db) + if err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to decrypt ssh key") + return + } + filename := fmt.Sprintf("%s_%s.pem", prefix, key.ID.String()) + w.Header().Set("Content-Type", "application/x-pem-file") + w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename)) + _, _ = w.Write([]byte(plain)) + return + + case "both": + plain, err := utils.DecryptForOrg(orgID, key.EncryptedPrivateKey, key.PrivateIV, key.PrivateTag, db) + if err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "failed to decrypt ssh key") + return + } + + var buf bytes.Buffer + zw := zip.NewWriter(&buf) + _ = toZipFile(fmt.Sprintf("%s_%s.pem", prefix, key.ID.String()), []byte(plain), zw) + _ = toZipFile(fmt.Sprintf("%s_%s.pub", prefix, key.ID.String()), []byte(key.PublicKey), zw) + _ = zw.Close() + + filename := fmt.Sprintf("ssh_key_%s.zip", key.ID.String()) + w.Header().Set("Content-Type", "application/zip") + w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename)) + _, _ = w.Write(buf.Bytes()) + return + + default: + utils.WriteError(w, http.StatusBadRequest, "invalid_ssh_part", "invalid part (public|private|both)") + return + } + } +} + +// --- Helpers --- + +func allowedBits(b int) bool { + return b == 2048 || b == 3072 || b == 4096 +} + +func GenerateRSA(bits int) (*rsa.PrivateKey, error) { + return rsa.GenerateKey(rand.Reader, bits) +} + +func RSAPrivateToPEMAndAuthorized(priv *rsa.PrivateKey, comment string) (privPEM string, authorized string, err error) { + der := x509.MarshalPKCS1PrivateKey(priv) + block := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: der} + var buf bytes.Buffer + if err = pem.Encode(&buf, block); err != nil { + return "", "", err + } + + pub, err := ssh.NewPublicKey(&priv.PublicKey) + if err != nil { + return "", "", err + } + auth := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(pub))) + comment = strings.TrimSpace(comment) + if comment != "" { + auth += " " + comment + } + return buf.String(), auth, nil +} + +func GenerateRSAPEMAndAuthorized(bits int, comment string) (string, string, error) { + priv, err := GenerateRSA(bits) + if err != nil { + return "", "", err + } + return RSAPrivateToPEMAndAuthorized(priv, comment) +} + +func toZipFile(filename string, content []byte, zw *zip.Writer) error { + f, err := zw.Create(filename) + if err != nil { + return err + } + _, err = f.Write(content) + return err +} + +func keyFilenamePrefix(pubAuth string) string { + // OpenSSH authorized keys start with the algorithm name + if strings.HasPrefix(pubAuth, "ssh-ed25519 ") { + return "id_ed25519" + } + // default to RSA + return "id_rsa" +} + +func GenerateEd25519PEMAndAuthorized(comment string) (privPEM string, authorized string, err error) { + // Generate ed25519 keypair + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return "", "", err + } + + // Private: PKCS#8 PEM + der, err := x509.MarshalPKCS8PrivateKey(priv) + if err != nil { + return "", "", err + } + block := &pem.Block{Type: "PRIVATE KEY", Bytes: der} + var buf bytes.Buffer + if err := pem.Encode(&buf, block); err != nil { + return "", "", err + } + + // Public: OpenSSH authorized_key + sshPub, err := ssh.NewPublicKey(ed25519.PublicKey(pub)) + if err != nil { + return "", "", err + } + auth := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(sshPub))) + comment = strings.TrimSpace(comment) + if comment != "" { + auth += " " + comment + } + + return buf.String(), auth, nil +} diff --git a/internal/handlers/taints.go b/internal/handlers/taints.go new file mode 100644 index 0000000..b2c5afa --- /dev/null +++ b/internal/handlers/taints.go @@ -0,0 +1,335 @@ +package handlers + +import ( + "encoding/json" + "errors" + "net/http" + "strings" + + "github.com/glueops/autoglue/internal/api/httpmiddleware" + "github.com/glueops/autoglue/internal/handlers/dto" + "github.com/glueops/autoglue/internal/models" + "github.com/glueops/autoglue/internal/utils" + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + "gorm.io/gorm" +) + +// ListTaints godoc +// @ID ListTaints +// @Summary List node pool taints (org scoped) +// @Description Returns node taints for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools. +// @Tags Taints +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param key query string false "Exact key" +// @Param value query string false "Exact value" +// @Param q query string false "key contains (case-insensitive)" +// @Success 200 {array} dto.TaintResponse +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "failed to list node taints" +// @Router /taints [get] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func ListTaints(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + q := db.Where("organization_id = ?", orgID) + + if key := strings.TrimSpace(r.URL.Query().Get("key")); key != "" { + q = q.Where(`key = ?`, key) + } + if val := strings.TrimSpace(r.URL.Query().Get("value")); val != "" { + q = q.Where(`value = ?`, val) + } + if needle := strings.TrimSpace(r.URL.Query().Get("q")); needle != "" { + q = q.Where(`key ILIKE ?`, "%"+needle+"%") + } + + var rows []models.Taint + if err := q.Order("created_at DESC").Find(&rows).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error") + return + } + + out := make([]dto.TaintResponse, 0, len(rows)) + for _, row := range rows { + out = append(out, dto.TaintResponse{ + ID: row.ID, + Key: row.Key, + Value: row.Value, + Effect: row.Effect, + }) + } + utils.WriteJSON(w, http.StatusOK, out) + } +} + +// GetTaint godoc +// @ID GetTaint +// @Summary Get node taint by ID (org scoped) +// @Tags Taints +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param id path string true "Node Taint ID (UUID)" +// @Success 200 {object} dto.TaintResponse +// @Failure 400 {string} string "invalid id" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 404 {string} string "not found" +// @Failure 500 {string} string "fetch failed" +// @Router /taints/{id} [get] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func GetTaint(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "bad request") + return + } + + var row models.Taint + if err := db.Where("id = ? AND organization_id = ?", id, orgID).First(&row).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + utils.WriteError(w, http.StatusNotFound, "not_found", "not_found") + return + } + utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error") + return + } + out := dto.TaintResponse{ + ID: row.ID, + Key: row.Key, + Value: row.Value, + Effect: row.Effect, + } + utils.WriteJSON(w, http.StatusOK, out) + } +} + +// CreateTaint godoc +// @ID CreateTaint +// @Summary Create node taint (org scoped) +// @Description Creates a taint. +// @Tags Taints +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param body body dto.CreateTaintRequest true "Taint payload" +// @Success 201 {object} dto.TaintResponse +// @Failure 400 {string} string "invalid json / missing fields / invalid node_pool_ids" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "create failed" +// @Router /taints [post] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func CreateTaint(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + var req dto.CreateTaintRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "bad request") + return + } + + req.Key = strings.TrimSpace(req.Key) + req.Value = strings.TrimSpace(req.Value) + req.Effect = strings.TrimSpace(req.Effect) + + if req.Key == "" || req.Value == "" || req.Effect == "" { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "missing key/value/effect") + return + } + + if _, ok := allowedEffects[req.Effect]; !ok { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "invalid effect") + return + } + + t := models.Taint{ + OrganizationID: orgID, + Key: req.Key, + Value: req.Value, + Effect: req.Effect, + } + if err := db.Create(&t).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error") + return + } + + out := dto.TaintResponse{ + ID: t.ID, + Key: t.Key, + Value: t.Value, + Effect: t.Effect, + } + utils.WriteJSON(w, http.StatusCreated, out) + } +} + +// UpdateTaint godoc +// @ID UpdateTaint +// @Summary Update node taint (org scoped) +// @Description Partially update taint fields. +// @Tags Taints +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param id path string true "Node Taint ID (UUID)" +// @Param body body dto.UpdateTaintRequest true "Fields to update" +// @Success 200 {object} dto.TaintResponse +// @Failure 400 {string} string "invalid id / invalid json" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 404 {string} string "not found" +// @Failure 500 {string} string "update failed" +// @Router /taints/{id} [patch] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func UpdateTaint(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "bad request") + return + } + + var t models.Taint + if err := db.Where("id = ? AND organization_id = ?", id, orgID).First(&t).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + utils.WriteError(w, http.StatusNotFound, "not_found", "not_found") + return + } + utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error") + return + } + + var req dto.UpdateTaintRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "bad request") + return + } + + next := t + + if req.Key != nil { + next.Key = strings.TrimSpace(*req.Key) + } + if req.Value != nil { + next.Value = strings.TrimSpace(*req.Value) + } + if req.Effect != nil { + e := strings.TrimSpace(*req.Effect) + if e == "" { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "missing effect") + return + } + if _, ok := allowedEffects[e]; !ok { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "invalid effect") + return + } + next.Effect = e + } + + if err := db.Save(&next).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error") + return + } + + out := dto.TaintResponse{ + ID: next.ID, + Key: next.Key, + Value: next.Value, + Effect: next.Effect, + } + utils.WriteJSON(w, http.StatusOK, out) + } +} + +// DeleteTaint godoc +// @ID DeleteTaint +// @Summary Delete taint (org scoped) +// @Description Permanently deletes the taint. +// @Tags Taints +// @Accept json +// @Produce json +// @Param X-Org-ID header string false "Organization UUID" +// @Param id path string true "Node Taint ID (UUID)" +// @Success 204 {string} string "No Content" +// @Failure 400 {string} string "invalid id" +// @Failure 401 {string} string "Unauthorized" +// @Failure 403 {string} string "organization required" +// @Failure 500 {string} string "delete failed" +// @Router /taints/{id} [delete] +// @Security BearerAuth +// @Security OrgKeyAuth +// @Security OrgSecretAuth +func DeleteTaint(db *gorm.DB) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + orgID, ok := httpmiddleware.OrgIDFrom(r.Context()) + if !ok { + utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID") + return + } + + id, err := uuid.Parse(chi.URLParam(r, "id")) + if err != nil { + utils.WriteError(w, http.StatusBadRequest, "bad_request", "bad request") + return + } + + var row models.Taint + if err := db.Where("id = ? AND organization_id = ?", id, orgID).First(&row).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + utils.WriteError(w, http.StatusNotFound, "not_found", "not_found") + return + } + utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error") + return + } + + if err := db.Delete(&row).Error; err != nil { + utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error") + return + } + w.WriteHeader(http.StatusNoContent) + } +} + +// --- Helpers --- +var allowedEffects = map[string]struct{}{ + "NoSchedule": {}, + "PreferNoSchedule": {}, + "NoExecute": {}, +} diff --git a/internal/keys/base64util.go b/internal/keys/base64util.go new file mode 100644 index 0000000..6dcfb1c --- /dev/null +++ b/internal/keys/base64util.go @@ -0,0 +1,35 @@ +package keys + +import ( + "encoding/base64" + "errors" + "strings" +) + +func decode32ByteKey(s string) ([]byte, error) { + try := func(enc *base64.Encoding, v string) ([]byte, bool) { + if b, err := enc.DecodeString(v); err == nil && len(b) == 32 { + return b, true + } + return nil, false + } + + // Try raw (no padding) variants first + if b, ok := try(base64.RawURLEncoding, s); ok { + return b, nil + } + if b, ok := try(base64.RawStdEncoding, s); ok { + return b, nil + } + + // Try padded variants (add padding if missing) + pad := func(v string) string { return v + strings.Repeat("=", (4-len(v)%4)%4) } + if b, ok := try(base64.URLEncoding, pad(s)); ok { + return b, nil + } + if b, ok := try(base64.StdEncoding, pad(s)); ok { + return b, nil + } + + return nil, errors.New("key must be 32 bytes in base64/base64url") +} diff --git a/internal/keys/export.go b/internal/keys/export.go new file mode 100644 index 0000000..216ae65 --- /dev/null +++ b/internal/keys/export.go @@ -0,0 +1,5 @@ +package keys + +func Decrypt(encKeyB64, enc string) ([]byte, error) { + return decryptAESGCM(encKeyB64, enc) +} diff --git a/internal/keys/keys.go b/internal/keys/keys.go new file mode 100644 index 0000000..0ae7502 --- /dev/null +++ b/internal/keys/keys.go @@ -0,0 +1,149 @@ +package keys + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/ed25519" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "errors" + "fmt" + "time" + + "github.com/glueops/autoglue/internal/models" + "github.com/google/uuid" + "gorm.io/gorm" +) + +type GenOpts struct { + Alg string // "RS256"|"RS384"|"RS512"|"EdDSA" + Bits int // RSA bits (2048/3072/4096). ignored for EdDSA + KID string // optional; if empty we generate one + NBF *time.Time + EXP *time.Time +} + +func GenerateAndStore(db *gorm.DB, encKeyB64 string, opts GenOpts) (*models.SigningKey, error) { + if opts.KID == "" { + opts.KID = uuid.NewString() + } + + var pubPEM, privPEM []byte + var alg = opts.Alg + + switch alg { + case "RS256", "RS384", "RS512": + if opts.Bits == 0 { + opts.Bits = 3072 + } + priv, err := rsa.GenerateKey(rand.Reader, opts.Bits) + if err != nil { + return nil, err + } + privDER := x509.MarshalPKCS1PrivateKey(priv) + privPEM = pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: privDER}) + + pubDER := x509.MarshalPKCS1PublicKey(&priv.PublicKey) + pubPEM = pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pubDER}) + + case "EdDSA": + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return nil, err + } + privDER, err := x509.MarshalPKCS8PrivateKey(priv) + if err != nil { + return nil, err + } + privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privDER}) + + pubDER, err := x509.MarshalPKIXPublicKey(pub) + if err != nil { + return nil, err + } + pubPEM = pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubDER}) + + default: + return nil, fmt.Errorf("unsupported alg: %s", alg) + } + + privateOut := string(privPEM) + if encKeyB64 != "" { + enc, err := encryptAESGCM(encKeyB64, privPEM) + if err != nil { + return nil, err + } + privateOut = enc + } + + rec := models.SigningKey{ + Kid: opts.KID, + Alg: alg, + Use: "sig", + IsActive: true, + PublicPEM: string(pubPEM), + PrivatePEM: privateOut, + NotBefore: opts.NBF, + ExpiresAt: opts.EXP, + } + if err := db.Create(&rec).Error; err != nil { + return nil, err + } + return &rec, nil +} + +func encryptAESGCM(b64 string, plaintext []byte) (string, error) { + key, err := decode32ByteKey(b64) + if err != nil { + return "", err + } + if len(key) != 32 { + return "", errors.New("JWT_PRIVATE_ENC_KEY must be 32 bytes (base64url)") + } + block, err := aes.NewCipher(key) + if err != nil { + return "", err + } + aead, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + nonce := make([]byte, aead.NonceSize()) + if _, err = rand.Read(nonce); err != nil { + return "", err + } + out := aead.Seal(nonce, nonce, plaintext, nil) + return "enc:aesgcm:" + base64.RawStdEncoding.EncodeToString(out), nil +} + +func decryptAESGCM(b64 string, enc string) ([]byte, error) { + if !bytes.HasPrefix([]byte(enc), []byte("enc:aesgcm:")) { + return nil, errors.New("not encrypted") + } + key, err := decode32ByteKey(b64) + if err != nil { + return nil, err + } + blob, err := base64.RawStdEncoding.DecodeString(enc[len("enc:aesgcm:"):]) + if err != nil { + return nil, err + } + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + aead, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + nonceSize := aead.NonceSize() + if len(blob) < nonceSize { + return nil, errors.New("ciphertext too short") + } + nonce, ct := blob[:nonceSize], blob[nonceSize:] + return aead.Open(nil, nonce, ct, nil) +} diff --git a/internal/models/account.go b/internal/models/account.go new file mode 100644 index 0000000..88ad2b5 --- /dev/null +++ b/internal/models/account.go @@ -0,0 +1,23 @@ +package models + +import ( + "time" + + "github.com/google/uuid" + "gorm.io/datatypes" +) + +type Account struct { + // example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"` + UserID uuid.UUID `gorm:"index;not null" json:"user_id" format:"uuid"` + User User `gorm:"foreignKey:UserID" json:"-"` + Provider string `gorm:"not null" json:"provider"` + Subject string `gorm:"not null" json:"subject"` + Email *string `json:"email,omitempty"` + EmailVerified bool `gorm:"not null;default:false" json:"email_verified"` + Profile datatypes.JSON `gorm:"type:jsonb;not null;default:'{}'" json:"profile"` + SecretHash *string `json:"-"` + CreatedAt time.Time `gorm:"type:timestamptz;column:created_at;not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"type:timestamptz;autoUpdateTime;column:updated_at;not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/api_key.go b/internal/models/api_key.go new file mode 100644 index 0000000..a260b1d --- /dev/null +++ b/internal/models/api_key.go @@ -0,0 +1,23 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type APIKey struct { + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"` + Name string `gorm:"not null;default:''" json:"name"` + KeyHash string `gorm:"uniqueIndex;not null" json:"-"` + Scope string `gorm:"not null;default:''" json:"scope"` + UserID *uuid.UUID `json:"user_id,omitempty" format:"uuid"` + OrgID *uuid.UUID `json:"org_id,omitempty" format:"uuid"` + SecretHash *string `json:"-"` + ExpiresAt *time.Time `json:"expires_at,omitempty" format:"date-time"` + Revoked bool `gorm:"not null;default:false" json:"revoked"` + Prefix *string `json:"prefix,omitempty"` + LastUsedAt *time.Time `json:"last_used_at,omitempty" format:"date-time"` + CreatedAt time.Time `gorm:"not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/master_key.go b/internal/models/master_key.go new file mode 100644 index 0000000..224bdec --- /dev/null +++ b/internal/models/master_key.go @@ -0,0 +1,15 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type MasterKey struct { + ID uuid.UUID `gorm:"type:uuid;default:gen_random_uuid();primaryKey" json:"id"` + Key string `gorm:"not null"` + IsActive bool `gorm:"default:true"` + CreatedAt time.Time `gorm:"column:created_at;not null;default:now()" json:"created_at"` + UpdatedAt time.Time `gorm:"autoUpdateTime;column:updated_at;not null;default:now()" json:"updated_at"` +} diff --git a/internal/models/membership.go b/internal/models/membership.go new file mode 100644 index 0000000..3f19059 --- /dev/null +++ b/internal/models/membership.go @@ -0,0 +1,18 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type Membership struct { + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"` + UserID uuid.UUID `gorm:"index;not null" json:"user_id" format:"uuid"` + User User `gorm:"foreignKey:UserID" json:"-"` + OrganizationID uuid.UUID `gorm:"index;not null" json:"org_id" format:"uuid"` + Organization Organization `gorm:"foreignKey:OrganizationID;constraint:OnDelete:CASCADE" json:"-"` + Role string `gorm:"not null;default:'member'" json:"role"` + CreatedAt time.Time `gorm:"not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/node_pool.go b/internal/models/node_pool.go new file mode 100644 index 0000000..bd5a29d --- /dev/null +++ b/internal/models/node_pool.go @@ -0,0 +1,21 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type NodePool struct { + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"` + OrganizationID uuid.UUID `gorm:"type:uuid;not null" json:"organization_id"` + Organization Organization `gorm:"foreignKey:OrganizationID;constraint:OnDelete:CASCADE" json:"organization"` + Name string `gorm:"not null" json:"name"` + Servers []Server `gorm:"many2many:node_servers;constraint:OnDelete:CASCADE" json:"servers,omitempty"` + //Annotations []Annotation `gorm:"many2many:node_annotations;constraint:OnDelete:CASCADE" json:"annotations,omitempty"` + //Labels []Label `gorm:"many2many:node_labels;constraint:OnDelete:CASCADE" json:"labels,omitempty"` + Taints []Taint `gorm:"many2many:node_taints;constraint:OnDelete:CASCADE" json:"taints,omitempty"` + //Clusters []Cluster `gorm:"many2many:cluster_node_pools;constraint:OnDelete:CASCADE" json:"clusters,omitempty"` + CreatedAt time.Time `gorm:"not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/organization-key.go b/internal/models/organization-key.go new file mode 100644 index 0000000..fc0eef5 --- /dev/null +++ b/internal/models/organization-key.go @@ -0,0 +1,20 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type OrganizationKey struct { + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"` + OrganizationID uuid.UUID `gorm:"type:uuid;not null" json:"organization_id"` + Organization Organization `gorm:"foreignKey:OrganizationID;constraint:OnDelete:CASCADE" json:"organization"` + MasterKeyID uuid.UUID `gorm:"type:uuid;not null"` + MasterKey MasterKey `gorm:"foreignKey:MasterKeyID;constraint:OnDelete:CASCADE" json:"master_key"` + EncryptedKey string `gorm:"not null"` + IV string `gorm:"not null"` + Tag string `gorm:"not null"` + CreatedAt time.Time `gorm:"not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/organization.go b/internal/models/organization.go new file mode 100644 index 0000000..d3f5ab9 --- /dev/null +++ b/internal/models/organization.go @@ -0,0 +1,16 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type Organization struct { + // example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"` + Name string `gorm:"not null" json:"name"` + Domain *string `gorm:"index" json:"domain"` + CreatedAt time.Time `gorm:"column:created_at;not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"autoUpdateTime;column:updated_at;not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/refresh_token.go b/internal/models/refresh_token.go new file mode 100644 index 0000000..ff0b8a3 --- /dev/null +++ b/internal/models/refresh_token.go @@ -0,0 +1,17 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type RefreshToken struct { + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"` + UserID uuid.UUID `gorm:"index;not null" json:"user_id"` + FamilyID uuid.UUID `gorm:"type:uuid;index;not null" json:"family_id"` + TokenHash string `gorm:"uniqueIndex;not null" json:"-"` + ExpiresAt time.Time `gorm:"not null" json:"expires_at"` + RevokedAt *time.Time `json:"revoked_at"` + CreatedAt time.Time `gorm:"not null;default:now()" json:"created_at"` +} diff --git a/internal/models/server.go b/internal/models/server.go new file mode 100644 index 0000000..ce5c3fd --- /dev/null +++ b/internal/models/server.go @@ -0,0 +1,36 @@ +package models + +import ( + "errors" + "strings" + "time" + + "github.com/google/uuid" + "gorm.io/gorm" +) + +type Server struct { + ID uuid.UUID `gorm:"type:uuid;default:gen_random_uuid();primaryKey" json:"id"` + OrganizationID uuid.UUID `gorm:"type:uuid;not null" json:"organization_id"` + Organization Organization `gorm:"foreignKey:OrganizationID;constraint:OnDelete:CASCADE" json:"organization"` + Hostname string `json:"hostname"` + PublicIPAddress *string `json:"public_ip_address,omitempty"` + PrivateIPAddress string `gorm:"not null" json:"private_ip_address"` + SSHUser string `gorm:"not null" json:"ssh_user"` + SshKeyID uuid.UUID `gorm:"type:uuid;not null" json:"ssh_key_id"` + SshKey SshKey `gorm:"foreignKey:SshKeyID" json:"ssh_key"` + Role string `gorm:"not null" json:"role"` // e.g., "master", "worker", "bastion" + Status string `gorm:"default:'pending'" json:"status"` // pending, provisioning, ready, failed + CreatedAt time.Time `gorm:"not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"not null;default:now()" json:"updated_at" format:"date-time"` +} + +func (s *Server) BeforeSave(tx *gorm.DB) error { + role := strings.ToLower(strings.TrimSpace(s.Role)) + if role == "bastion" { + if s.PublicIPAddress == nil || strings.TrimSpace(*s.PublicIPAddress) == "" { + return errors.New("public_ip_address is required for role=bastion") + } + } + return nil +} diff --git a/internal/models/signing_key.go b/internal/models/signing_key.go new file mode 100644 index 0000000..51258f3 --- /dev/null +++ b/internal/models/signing_key.go @@ -0,0 +1,22 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type SigningKey struct { + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"` + Kid string `gorm:"uniqueIndex;not null" json:"kid"` // key id (header 'kid') + Alg string `gorm:"not null" json:"alg"` // RS256|RS384|RS512|EdDSA + Use string `gorm:"not null;default:'sig'" json:"use"` // "sig" + IsActive bool `gorm:"not null;default:true" json:"is_active"` + PublicPEM string `gorm:"type:text;not null" json:"-"` + PrivatePEM string `gorm:"type:text;not null" json:"-"` + NotBefore *time.Time `json:"-"` + ExpiresAt *time.Time `json:"-"` + CreatedAt time.Time `gorm:"not null;default:now()" json:"created_at"` + UpdatedAt time.Time `gorm:"not null;default:now()" json:"updated_at"` + RotatedFrom *uuid.UUID `json:"-"` // previous key id, if any +} diff --git a/internal/models/ssh-key.go b/internal/models/ssh-key.go new file mode 100644 index 0000000..1119b0c --- /dev/null +++ b/internal/models/ssh-key.go @@ -0,0 +1,21 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type SshKey struct { + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"` + OrganizationID uuid.UUID `gorm:"type:uuid;not null" json:"organization_id"` + Organization Organization `gorm:"foreignKey:OrganizationID;constraint:OnDelete:CASCADE" json:"organization"` + Name string `gorm:"not null" json:"name"` + PublicKey string `gorm:"not null"` + EncryptedPrivateKey string `gorm:"not null"` + PrivateIV string `gorm:"not null"` + PrivateTag string `gorm:"not null"` + Fingerprint string `gorm:"not null;index" json:"fingerprint"` + CreatedAt time.Time `gorm:"not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/taint.go b/internal/models/taint.go new file mode 100644 index 0000000..38a0869 --- /dev/null +++ b/internal/models/taint.go @@ -0,0 +1,18 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type Taint struct { + ID uuid.UUID `gorm:"type:uuid;default:gen_random_uuid();primaryKey" json:"id"` + OrganizationID uuid.UUID `gorm:"type:uuid;not null" json:"organization_id"` + Organization Organization `gorm:"foreignKey:OrganizationID;constraint:OnDelete:CASCADE" json:"organization"` + Key string `gorm:"not null" json:"key"` + Value string `gorm:"not null" json:"value"` + Effect string `gorm:"not null" json:"effect"` + CreatedAt time.Time `gorm:"column:created_at;not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"autoUpdateTime;column:updated_at;not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/user.go b/internal/models/user.go new file mode 100644 index 0000000..8273cc5 --- /dev/null +++ b/internal/models/user.go @@ -0,0 +1,18 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type User struct { + // example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"` + DisplayName *string `json:"display_name,omitempty"` + PrimaryEmail *string `json:"primary_email,omitempty"` + AvatarURL *string `json:"avatar_url,omitempty"` + IsDisabled bool `json:"is_disabled"` + CreatedAt time.Time `gorm:"column:created_at;not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"autoUpdateTime;column:updated_at;not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/models/user_email.go b/internal/models/user_email.go new file mode 100644 index 0000000..9daf316 --- /dev/null +++ b/internal/models/user_email.go @@ -0,0 +1,19 @@ +package models + +import ( + "time" + + "github.com/google/uuid" +) + +type UserEmail struct { + // example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"` + UserID uuid.UUID `gorm:"index;not null" json:"user_id" format:"uuid"` + User User `gorm:"foreignKey:UserID" json:"user"` + Email string `gorm:"not null" json:"email"` + IsVerified bool `gorm:"not null;default:false" json:"is_verified"` + IsPrimary bool `gorm:"not null;default:false" json:"is_primary"` + CreatedAt time.Time `gorm:"column:created_at;not null;default:now()" json:"created_at" format:"date-time"` + UpdatedAt time.Time `gorm:"autoUpdateTime;column:updated_at;not null;default:now()" json:"updated_at" format:"date-time"` +} diff --git a/internal/utils/crypto.go b/internal/utils/crypto.go new file mode 100644 index 0000000..3207b36 --- /dev/null +++ b/internal/utils/crypto.go @@ -0,0 +1,85 @@ +package utils + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "errors" + "fmt" + "io" +) + +var ( + ErrNoActiveMasterKey = errors.New("no active master key found") + ErrInvalidOrgID = errors.New("invalid organization ID") + ErrCredentialNotFound = errors.New("credential not found") + ErrInvalidMasterKeyLen = errors.New("invalid master key length") +) + +func randomBytes(n int) ([]byte, error) { + b := make([]byte, n) + if _, err := io.ReadFull(rand.Reader, b); err != nil { + return nil, fmt.Errorf("rand: %w", err) + } + return b, nil +} + +func encryptAESGCM(plaintext, key []byte) (cipherNoTag, iv, tag []byte, _ error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, nil, nil, fmt.Errorf("cipher: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, nil, nil, fmt.Errorf("gcm: %w", err) + } + if gcm.NonceSize() != 12 { + return nil, nil, nil, fmt.Errorf("unexpected nonce size: %d", gcm.NonceSize()) + } + + iv, err = randomBytes(gcm.NonceSize()) + if err != nil { + return nil, nil, nil, err + } + + // Go’s GCM returns ciphertext||tag, with 16-byte tag. + cipherWithTag := gcm.Seal(nil, iv, plaintext, nil) + if len(cipherWithTag) < 16 { + return nil, nil, nil, errors.New("ciphertext too short") + } + tagLen := 16 + cipherNoTag = cipherWithTag[:len(cipherWithTag)-tagLen] + tag = cipherWithTag[len(cipherWithTag)-tagLen:] + return cipherNoTag, iv, tag, nil +} + +func decryptAESGCM(cipherNoTag, key, iv, tag []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, fmt.Errorf("cipher: %w", err) + } + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, fmt.Errorf("gcm: %w", err) + } + if gcm.NonceSize() != len(iv) { + return nil, fmt.Errorf("bad nonce size: %d", len(iv)) + } + // Reattach tag + cipherWithTag := append(append([]byte{}, cipherNoTag...), tag...) + plain, err := gcm.Open(nil, iv, cipherWithTag, nil) + if err != nil { + return nil, fmt.Errorf("gcm open: %w", err) + } + return plain, nil +} + +func EncodeB64(b []byte) string { + return base64.StdEncoding.EncodeToString(b) +} + +func DecodeB64(s string) ([]byte, error) { + return base64.StdEncoding.DecodeString(s) +} diff --git a/internal/utils/helpers.go b/internal/utils/helpers.go new file mode 100644 index 0000000..cc3121c --- /dev/null +++ b/internal/utils/helpers.go @@ -0,0 +1,27 @@ +package utils + +import ( + "encoding/json" + "net/http" +) + +// ErrorResponse is a simple, reusable error payload. +// swagger:model ErrorResponse +type ErrorResponse struct { + // A machine-readable error code, e.g. "validation_error" + // example: validation_error + Code string `json:"code"` + // Human-readable message + // example: slug is required + Message string `json:"message"` +} + +func WriteJSON(w http.ResponseWriter, status int, v any) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + _ = json.NewEncoder(w).Encode(v) +} + +func WriteError(w http.ResponseWriter, status int, code, msg string) { + WriteJSON(w, status, ErrorResponse{Code: code, Message: msg}) +} diff --git a/internal/utils/keys.go b/internal/utils/keys.go new file mode 100644 index 0000000..b8a7202 --- /dev/null +++ b/internal/utils/keys.go @@ -0,0 +1,107 @@ +package utils + +import ( + "encoding/base64" + "errors" + "fmt" + + "github.com/glueops/autoglue/internal/models" + "github.com/google/uuid" + "gorm.io/gorm" +) + +func getMasterKey(db *gorm.DB) ([]byte, error) { + var mk models.MasterKey + if err := db.Where("is_active = ?", true).Order("created_at DESC").First(&mk).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrNoActiveMasterKey + } + return nil, fmt.Errorf("querying master key: %w", err) + } + + keyBytes, err := base64.StdEncoding.DecodeString(mk.Key) + if err != nil { + return nil, fmt.Errorf("decoding master key: %w", err) + } + if len(keyBytes) != 32 { + return nil, fmt.Errorf("%w: got %d, want 32", ErrInvalidMasterKeyLen, len(keyBytes)) + } + return keyBytes, nil +} + +func getOrCreateTenantKey(orgID string, db *gorm.DB) ([]byte, error) { + var orgKey models.OrganizationKey + err := db.Where("organization_id = ?", orgID).First(&orgKey).Error + if err == nil { + encKeyB64 := orgKey.EncryptedKey + ivB64 := orgKey.IV + tagB64 := orgKey.Tag + + encryptedKey, err := DecodeB64(encKeyB64) + if err != nil { + return nil, fmt.Errorf("decode enc key: %w", err) + } + + iv, err := DecodeB64(ivB64) + if err != nil { + return nil, fmt.Errorf("decode iv: %w", err) + } + + tag, err := DecodeB64(tagB64) + if err != nil { + return nil, fmt.Errorf("decode tag: %w", err) + } + + masterKey, err := getMasterKey(db) + if err != nil { + return nil, err + } + + return decryptAESGCM(encryptedKey, masterKey, iv, tag) + } + + if !errors.Is(err, gorm.ErrRecordNotFound) { + return nil, err + } + + // Create new tenant key and wrap with the current master key + orgUUID, err := uuid.Parse(orgID) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrInvalidOrgID, err) + } + + tenantKey, err := randomBytes(32) + if err != nil { + return nil, fmt.Errorf("tenant key gen: %w", err) + } + + masterKey, err := getMasterKey(db) + if err != nil { + return nil, err + } + + encrypted, iv, tag, err := encryptAESGCM(tenantKey, masterKey) + if err != nil { + return nil, fmt.Errorf("wrap tenant key: %w", err) + } + + var mk models.MasterKey + if err := db.Where("is_active = ?", true).Order("created_at DESC").First(&mk).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrNoActiveMasterKey + } + return nil, fmt.Errorf("querying master key: %w", err) + } + + orgKey = models.OrganizationKey{ + OrganizationID: orgUUID, + MasterKeyID: mk.ID, + EncryptedKey: EncodeB64(encrypted), + IV: EncodeB64(iv), + Tag: EncodeB64(tag), + } + if err := db.Create(&orgKey).Error; err != nil { + return nil, fmt.Errorf("persist org key: %w", err) + } + return tenantKey, nil +} diff --git a/internal/utils/org-crypto.go b/internal/utils/org-crypto.go new file mode 100644 index 0000000..de8d2ab --- /dev/null +++ b/internal/utils/org-crypto.go @@ -0,0 +1,44 @@ +package utils + +import ( + "fmt" + + "github.com/google/uuid" + "gorm.io/gorm" +) + +func EncryptForOrg(orgID uuid.UUID, plaintext []byte, db *gorm.DB) (cipherB64, ivB64, tagB64 string, err error) { + tenantKey, err := getOrCreateTenantKey(orgID.String(), db) + if err != nil { + return "", "", "", err + } + ct, iv, tag, err := encryptAESGCM(plaintext, tenantKey) + if err != nil { + return "", "", "", err + } + return EncodeB64(ct), EncodeB64(iv), EncodeB64(tag), nil +} + +func DecryptForOrg(orgID uuid.UUID, cipherB64, ivB64, tagB64 string, db *gorm.DB) (string, error) { + tenantKey, err := getOrCreateTenantKey(orgID.String(), db) + if err != nil { + return "", err + } + ct, err := DecodeB64(cipherB64) + if err != nil { + return "", fmt.Errorf("decode cipher: %w", err) + } + iv, err := DecodeB64(ivB64) + if err != nil { + return "", fmt.Errorf("decode iv: %w", err) + } + tag, err := DecodeB64(tagB64) + if err != nil { + return "", fmt.Errorf("decode tag: %w", err) + } + plain, err := decryptAESGCM(ct, tenantKey, iv, tag) + if err != nil { + return "", err + } + return string(plain), nil +} diff --git a/internal/version/version.go b/internal/version/version.go new file mode 100644 index 0000000..dad3901 --- /dev/null +++ b/internal/version/version.go @@ -0,0 +1,36 @@ +package version + +import ( + "fmt" + "runtime" + "runtime/debug" +) + +var ( + Version = "dev" + Commit = "none" + Date = "unknown" + BuiltBy = "local" +) + +func Info() string { + v := fmt.Sprintf("Version: %s\nCommit: %s\nBuilt: %s\nBuiltBy: %s\nGo: %s %s/%s", + Version, Commit, Date, BuiltBy, runtime.Version(), runtime.GOOS, runtime.GOARCH) + + // Include VCS info from embedded build metadata (if available) + if bi, ok := debug.ReadBuildInfo(); ok { + for _, s := range bi.Settings { + switch s.Key { + case "vcs": + v += fmt.Sprintf("\nVCS: %s", s.Value) + case "vcs.revision": + v += fmt.Sprintf("\nRevision: %s", s.Value) + case "vcs.time": + v += fmt.Sprintf("\nCommitTime: %s", s.Value) + case "vcs.modified": + v += fmt.Sprintf("\nModified: %s", s.Value) + } + } + } + return v +} diff --git a/internal/web/devproxy.go b/internal/web/devproxy.go new file mode 100644 index 0000000..4ed87bd --- /dev/null +++ b/internal/web/devproxy.go @@ -0,0 +1,16 @@ +package web + +import ( + "net/http" + "net/http/httputil" + "net/url" +) + +func DevProxy(target string) (http.Handler, error) { + u, err := url.Parse(target) + if err != nil { + return nil, err + } + p := httputil.NewSingleHostReverseProxy(u) + return p, nil +} diff --git a/internal/web/dist/assets/index-BvUUUOIq.css b/internal/web/dist/assets/index-BvUUUOIq.css new file mode 100644 index 0000000..c1ca743 --- /dev/null +++ b/internal/web/dist/assets/index-BvUUUOIq.css @@ -0,0 +1,2 @@ +/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--font-weight-medium:500;--font-weight-semibold:600;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab,var(--ring)50%,transparent)}}body{background-color:var(--background);color:var(--foreground)}}@layer components;@layer utilities{.\@container\/card-header{container:card-header/inline-size}.absolute{position:absolute}.relative{position:relative}.static{position:static}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.mx-auto{margin-inline:auto}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-9{width:calc(var(--spacing)*9);height:calc(var(--spacing)*9)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.w-full{width:100%}.max-w-md{max-width:var(--container-md)}.shrink-0{flex-shrink:0}.animate-spin{animation:var(--animate-spin)}.auto-rows-min{grid-auto-rows:min-content}.grid-rows-\[auto_auto\]{grid-template-rows:auto auto}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.self-start{align-self:flex-start}.justify-self-end{justify-self:flex-end}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.bg-background{background-color:var(--background)}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-primary{background-color:var(--primary)}.bg-secondary{background-color:var(--secondary)}.p-4{padding:calc(var(--spacing)*4)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-2{padding-block:calc(var(--spacing)*2)}.py-6{padding-block:calc(var(--spacing)*6)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-card-foreground{color:var(--card-foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-white{color:var(--color-white)}.underline-offset-4{text-underline-offset:4px}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive)90%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary)90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary)80%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(3px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab,var(--ring)50%,transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}.has-data-\[slot\=card-action\]\:grid-cols-\[1fr_auto\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-\[\>svg\]\:px-2\.5:has(>svg){padding-inline:calc(var(--spacing)*2.5)}.has-\[\>svg\]\:px-3:has(>svg){padding-inline:calc(var(--spacing)*3)}.has-\[\>svg\]\:px-4:has(>svg){padding-inline:calc(var(--spacing)*4)}.aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}@media (min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.md\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}.dark\:border-input:is(.dark *){border-color:var(--input)}.dark\:bg-destructive\/60:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-destructive\/60:is(.dark *){background-color:color-mix(in oklab,var(--destructive)60%,transparent)}}.dark\:bg-input\/30:is(.dark *){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-input\/30:is(.dark *){background-color:color-mix(in oklab,var(--input)30%,transparent)}}@media (hover:hover){.dark\:hover\:bg-accent\/50:is(.dark *):hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-accent\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--input)50%,transparent)}}}.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\.border-b\]\:pb-6.border-b{padding-bottom:calc(var(--spacing)*6)}.\[\.border-t\]\:pt-6.border-t{padding-top:calc(var(--spacing)*6)}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--radius:.625rem;--background:#fff;--foreground:#09090b;--card:#fff;--card-foreground:#09090b;--popover:#fff;--popover-foreground:#09090b;--primary:#18181b;--primary-foreground:#fafafa;--secondary:#f4f4f5;--secondary-foreground:#18181b;--muted:#f4f4f5;--muted-foreground:#71717b;--accent:#f4f4f5;--accent-foreground:#18181b;--destructive:#e40014;--border:#e4e4e7;--input:#e4e4e7;--ring:#9f9fa9;--chart-1:#f05100;--chart-2:#009588;--chart-3:#104e64;--chart-4:#fcbb00;--chart-5:#f99c00;--sidebar:#fafafa;--sidebar-foreground:#09090b;--sidebar-primary:#18181b;--sidebar-primary-foreground:#fafafa;--sidebar-accent:#f4f4f5;--sidebar-accent-foreground:#18181b;--sidebar-border:#e4e4e7;--sidebar-ring:#9f9fa9}@supports (color:lab(0% 0 0)){:root{--background:lab(100% 0 0);--foreground:lab(2.51107% .242703 -.886115);--card:lab(100% 0 0);--card-foreground:lab(2.51107% .242703 -.886115);--popover:lab(100% 0 0);--popover-foreground:lab(2.51107% .242703 -.886115);--primary:lab(8.30603% .618205 -2.16572);--primary-foreground:lab(98.26% 0 0);--secondary:lab(96.1634% .0993311 -.364041);--secondary-foreground:lab(8.30603% .618205 -2.16572);--muted:lab(96.1634% .0993311 -.364041);--muted-foreground:lab(47.8878% 1.65477 -5.77283);--accent:lab(96.1634% .0993311 -.364041);--accent-foreground:lab(8.30603% .618205 -2.16572);--destructive:lab(48.4493% 77.4328 61.5452);--border:lab(90.6853% .399232 -1.45452);--input:lab(90.6853% .399232 -1.45452);--ring:lab(65.6464% 1.53497 -5.42429);--chart-1:lab(57.1026% 64.2584 89.8886);--chart-2:lab(55.0223% -41.0774 -3.90277);--chart-3:lab(30.372% -13.1853 -18.7887);--chart-4:lab(80.1641% 16.6016 99.2089);--chart-5:lab(72.7183% 31.8672 97.9407);--sidebar:lab(98.26% 0 0);--sidebar-foreground:lab(2.51107% .242703 -.886115);--sidebar-primary:lab(8.30603% .618205 -2.16572);--sidebar-primary-foreground:lab(98.26% 0 0);--sidebar-accent:lab(96.1634% .0993311 -.364041);--sidebar-accent-foreground:lab(8.30603% .618205 -2.16572);--sidebar-border:lab(90.6853% .399232 -1.45452);--sidebar-ring:lab(65.6464% 1.53497 -5.42429)}}.dark{--background:#09090b;--foreground:#fafafa;--card:#18181b;--card-foreground:#fafafa;--popover:#18181b;--popover-foreground:#fafafa;--primary:#e4e4e7;--primary-foreground:#18181b;--secondary:#27272a;--secondary-foreground:#fafafa;--muted:#27272a;--muted-foreground:#9f9fa9;--accent:#27272a;--accent-foreground:#fafafa;--destructive:#ff6568;--border:#ffffff1a;--input:#ffffff26;--ring:#71717b;--chart-1:#1447e6;--chart-2:#00bb7f;--chart-3:#f99c00;--chart-4:#ac4bff;--chart-5:#ff2357;--sidebar:#18181b;--sidebar-foreground:#fafafa;--sidebar-primary:#1447e6;--sidebar-primary-foreground:#fafafa;--sidebar-accent:#27272a;--sidebar-accent-foreground:#fafafa;--sidebar-border:#ffffff1a;--sidebar-ring:#71717b}@supports (color:lab(0% 0 0)){.dark{--background:lab(2.51107% .242703 -.886115);--foreground:lab(98.26% 0 0);--card:lab(8.30603% .618205 -2.16572);--card-foreground:lab(98.26% 0 0);--popover:lab(8.30603% .618205 -2.16572);--popover-foreground:lab(98.26% 0 0);--primary:lab(90.6853% .399232 -1.45452);--primary-foreground:lab(8.30603% .618205 -2.16572);--secondary:lab(15.7305% .613764 -2.16959);--secondary-foreground:lab(98.26% 0 0);--muted:lab(15.7305% .613764 -2.16959);--muted-foreground:lab(65.6464% 1.53497 -5.42429);--accent:lab(15.7305% .613764 -2.16959);--accent-foreground:lab(98.26% 0 0);--destructive:lab(63.7053% 60.745 31.3109);--border:lab(100% 0 0/.1);--input:lab(100% 0 0/.15);--ring:lab(47.8878% 1.65477 -5.77283);--chart-1:lab(36.9089% 35.0961 -85.6872);--chart-2:lab(66.9756% -58.27 19.5419);--chart-3:lab(72.7183% 31.8672 97.9407);--chart-4:lab(52.0183% 66.11 -78.2316);--chart-5:lab(56.101% 79.4328 31.4532);--sidebar:lab(8.30603% .618205 -2.16572);--sidebar-foreground:lab(98.26% 0 0);--sidebar-primary:lab(36.9089% 35.0961 -85.6872);--sidebar-primary-foreground:lab(98.26% 0 0);--sidebar-accent:lab(15.7305% .613764 -2.16959);--sidebar-accent-foreground:lab(98.26% 0 0);--sidebar-border:lab(100% 0 0/.1);--sidebar-ring:lab(47.8878% 1.65477 -5.77283)}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes spin{to{transform:rotate(360deg)}} diff --git a/internal/web/dist/assets/index-BvUUUOIq.css.br b/internal/web/dist/assets/index-BvUUUOIq.css.br new file mode 100644 index 0000000..46489ad Binary files /dev/null and b/internal/web/dist/assets/index-BvUUUOIq.css.br differ diff --git a/internal/web/dist/assets/index-BvUUUOIq.css.gz b/internal/web/dist/assets/index-BvUUUOIq.css.gz new file mode 100644 index 0000000..0a33b3a Binary files /dev/null and b/internal/web/dist/assets/index-BvUUUOIq.css.gz differ diff --git a/internal/web/dist/assets/index-CFwByDWI.js b/internal/web/dist/assets/index-CFwByDWI.js new file mode 100644 index 0000000..2bd46c6 --- /dev/null +++ b/internal/web/dist/assets/index-CFwByDWI.js @@ -0,0 +1,10 @@ +import{r as py,a as by,b as W,R as _,c as Sy,u as xy,d as zy,e as Ey,f as mh,B as Ty}from"./react-BZmgNp9X.js";(function(){const c=document.createElement("link").relList;if(c&&c.supports&&c.supports("modulepreload"))return;for(const y of document.querySelectorAll('link[rel="modulepreload"]'))r(y);new MutationObserver(y=>{for(const v of y)if(v.type==="childList")for(const T of v.addedNodes)T.tagName==="LINK"&&T.rel==="modulepreload"&&r(T)}).observe(document,{childList:!0,subtree:!0});function o(y){const v={};return y.integrity&&(v.integrity=y.integrity),y.referrerPolicy&&(v.referrerPolicy=y.referrerPolicy),y.crossOrigin==="use-credentials"?v.credentials="include":y.crossOrigin==="anonymous"?v.credentials="omit":v.credentials="same-origin",v}function r(y){if(y.ep)return;y.ep=!0;const v=o(y);fetch(y.href,v)}})();var Pc={exports:{}},di={};var yh;function Ay(){if(yh)return di;yh=1;var u=Symbol.for("react.transitional.element"),c=Symbol.for("react.fragment");function o(r,y,v){var T=null;if(v!==void 0&&(T=""+v),y.key!==void 0&&(T=""+y.key),"key"in y){v={};for(var E in y)E!=="key"&&(v[E]=y[E])}else v=y;return y=v.ref,{$$typeof:u,type:r,key:T,ref:y!==void 0?y:null,props:v}}return di.Fragment=c,di.jsx=o,di.jsxs=o,di}var vh;function My(){return vh||(vh=1,Pc.exports=Ay()),Pc.exports}var I=My(),to={exports:{}},hi={},eo={exports:{}},ao={};var gh;function Oy(){return gh||(gh=1,(function(u){function c(S,N){var D=S.length;S.push(N);t:for(;0>>1,et=S[ct];if(0>>1;cty(U,D))Zy(nt,U)?(S[ct]=nt,S[Z]=D,ct=Z):(S[ct]=U,S[dt]=D,ct=dt);else if(Zy(nt,D))S[ct]=nt,S[Z]=D,ct=Z;else break t}}return N}function y(S,N){var D=S.sortIndex-N.sortIndex;return D!==0?D:S.id-N.id}if(u.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var v=performance;u.unstable_now=function(){return v.now()}}else{var T=Date,E=T.now();u.unstable_now=function(){return T.now()-E}}var O=[],C=[],H=1,h=null,R=3,K=!1,B=!1,L=!1,P=!1,X=typeof setTimeout=="function"?setTimeout:null,St=typeof clearTimeout=="function"?clearTimeout:null,st=typeof setImmediate<"u"?setImmediate:null;function Tt(S){for(var N=o(C);N!==null;){if(N.callback===null)r(C);else if(N.startTime<=S)r(C),N.sortIndex=N.expirationTime,c(O,N);else break;N=o(C)}}function at(S){if(L=!1,Tt(S),!B)if(o(O)!==null)B=!0,k||(k=!0,Dt());else{var N=o(C);N!==null&&Bt(at,N.startTime-S)}}var k=!1,At=-1,q=5,Ot=-1;function ue(){return P?!0:!(u.unstable_now()-OtS&&ue());){var ct=h.callback;if(typeof ct=="function"){h.callback=null,R=h.priorityLevel;var et=ct(h.expirationTime<=S);if(S=u.unstable_now(),typeof et=="function"){h.callback=et,Tt(S),N=!0;break e}h===o(O)&&r(O),Tt(S)}else r(O);h=o(O)}if(h!==null)N=!0;else{var wt=o(C);wt!==null&&Bt(at,wt.startTime-S),N=!1}}break t}finally{h=null,R=D,K=!1}N=void 0}}finally{N?Dt():k=!1}}}var Dt;if(typeof st=="function")Dt=function(){st(Gt)};else if(typeof MessageChannel<"u"){var kt=new MessageChannel,he=kt.port2;kt.port1.onmessage=Gt,Dt=function(){he.postMessage(null)}}else Dt=function(){X(Gt,0)};function Bt(S,N){At=X(function(){S(u.unstable_now())},N)}u.unstable_IdlePriority=5,u.unstable_ImmediatePriority=1,u.unstable_LowPriority=4,u.unstable_NormalPriority=3,u.unstable_Profiling=null,u.unstable_UserBlockingPriority=2,u.unstable_cancelCallback=function(S){S.callback=null},u.unstable_forceFrameRate=function(S){0>S||125ct?(S.sortIndex=D,c(C,S),o(O)===null&&S===o(C)&&(L?(St(At),At=-1):L=!0,Bt(at,D-ct))):(S.sortIndex=et,c(O,S),B||K||(B=!0,k||(k=!0,Dt()))),S},u.unstable_shouldYield=ue,u.unstable_wrapCallback=function(S){var N=R;return function(){var D=R;R=N;try{return S.apply(this,arguments)}finally{R=D}}}})(ao)),ao}var ph;function wy(){return ph||(ph=1,eo.exports=Oy()),eo.exports}var bh;function Dy(){if(bh)return hi;bh=1;var u=wy(),c=py(),o=by();function r(t){var e="https://react.dev/errors/"+t;if(1et||(t.current=ct[et],ct[et]=null,et--)}function U(t,e){et++,ct[et]=t.current,t.current=e}var Z=wt(null),nt=wt(null),_t=wt(null),gt=wt(null);function ht(t,e){switch(U(_t,e),U(nt,t),U(Z,null),e.nodeType){case 9:case 11:t=(t=e.documentElement)&&(t=t.namespaceURI)?qd(t):0;break;default:if(t=e.tagName,e=e.namespaceURI)e=qd(e),t=jd(e,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}dt(Z),U(Z,t)}function Ft(){dt(Z),dt(nt),dt(_t)}function Ae(t){t.memoizedState!==null&&U(gt,t);var e=Z.current,a=jd(e,t.type);e!==a&&(U(nt,t),U(Z,a))}function Me(t){nt.current===t&&(dt(Z),dt(nt)),gt.current===t&&(dt(gt),ci._currentValue=D)}var se,pi;function Ze(t){if(se===void 0)try{throw Error()}catch(a){var e=a.stack.trim().match(/\n( *(at )?)/);se=e&&e[1]||"",pi=-1)":-1n||d[l]!==b[n]){var A=` +`+d[l].replace(" at new "," at ");return t.displayName&&A.includes("")&&(A=A.replace("",t.displayName)),A}while(1<=l&&0<=n);break}}}finally{gn=!1,Error.prepareStackTrace=a}return(a=t?t.displayName||t.name:"")?Ze(a):""}function tl(t,e){switch(t.tag){case 26:case 27:case 5:return Ze(t.type);case 16:return Ze("Lazy");case 13:return t.child!==e&&e!==null?Ze("Suspense Fallback"):Ze("Suspense");case 19:return Ze("SuspenseList");case 0:case 15:return Al(t.type,!1);case 11:return Al(t.type.render,!1);case 1:return Al(t.type,!0);case 31:return Ze("Activity");default:return""}}function pn(t){try{var e="",a=null;do e+=tl(t,a),a=t,t=t.return;while(t);return e}catch(l){return` +Error generating stack: `+l.message+` +`+l.stack}}var Oe=Object.prototype.hasOwnProperty,bn=u.unstable_scheduleCallback,Sn=u.unstable_cancelCallback,ce=u.unstable_shouldYield,Ma=u.unstable_requestPaint,oe=u.unstable_now,Gu=u.unstable_getCurrentPriorityLevel,el=u.unstable_ImmediatePriority,bi=u.unstable_UserBlockingPriority,al=u.unstable_NormalPriority,xn=u.unstable_LowPriority,ua=u.unstable_IdlePriority,Si=u.log,Oa=u.unstable_setDisableYieldValue,ll=null,re=null;function Ke(t){if(typeof Si=="function"&&Oa(t),re&&typeof re.setStrictMode=="function")try{re.setStrictMode(ll,t)}catch{}}var ne=Math.clz32?Math.clz32:Ie,Xu=Math.log,zn=Math.LN2;function Ie(t){return t>>>=0,t===0?32:31-(Xu(t)/zn|0)|0}var Ml=256,Ol=262144,nl=4194304;function Pe(t){var e=t&42;if(e!==0)return e;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function F(t,e,a){var l=t.pendingLanes;if(l===0)return 0;var n=0,i=t.suspendedLanes,s=t.pingedLanes;t=t.warmLanes;var f=l&134217727;return f!==0?(l=f&~i,l!==0?n=Pe(l):(s&=f,s!==0?n=Pe(s):a||(a=f&~t,a!==0&&(n=Pe(a))))):(f=l&~i,f!==0?n=Pe(f):s!==0?n=Pe(s):a||(a=l&~t,a!==0&&(n=Pe(a)))),n===0?0:e!==0&&e!==n&&(e&i)===0&&(i=n&-n,a=e&-e,i>=a||i===32&&(a&4194048)!==0)?e:n}function Ut(t,e){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&e)===0}function Wt(t,e){switch(t){case 1:case 2:case 4:case 8:case 64:return e+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function ie(){var t=nl;return nl<<=1,(nl&62914560)===0&&(nl=4194304),t}function wa(t){for(var e=[],a=0;31>a;a++)e.push(t);return e}function Ht(t,e){t.pendingLanes|=e,e!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function me(t,e,a,l,n,i){var s=t.pendingLanes;t.pendingLanes=a,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=a,t.entangledLanes&=a,t.errorRecoveryDisabledLanes&=a,t.shellSuspendCounter=0;var f=t.entanglements,d=t.expirationTimes,b=t.hiddenUpdates;for(a=s&~a;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var dm=/[\n"\\]/g;function Be(t){return t.replace(dm,function(e){return"\\"+e.charCodeAt(0).toString(16)+" "})}function Ju(t,e,a,l,n,i,s,f){t.name="",s!=null&&typeof s!="function"&&typeof s!="symbol"&&typeof s!="boolean"?t.type=s:t.removeAttribute("type"),e!=null?s==="number"?(e===0&&t.value===""||t.value!=e)&&(t.value=""+He(e)):t.value!==""+He(e)&&(t.value=""+He(e)):s!=="submit"&&s!=="reset"||t.removeAttribute("value"),e!=null?ku(t,s,He(e)):a!=null?ku(t,s,He(a)):l!=null&&t.removeAttribute("value"),n==null&&i!=null&&(t.defaultChecked=!!i),n!=null&&(t.checked=n&&typeof n!="function"&&typeof n!="symbol"),f!=null&&typeof f!="function"&&typeof f!="symbol"&&typeof f!="boolean"?t.name=""+He(f):t.removeAttribute("name")}function Co(t,e,a,l,n,i,s,f){if(i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(t.type=i),e!=null||a!=null){if(!(i!=="submit"&&i!=="reset"||e!=null)){Ku(t);return}a=a!=null?""+He(a):"",e=e!=null?""+He(e):a,f||e===t.value||(t.value=e),t.defaultValue=e}l=l??n,l=typeof l!="function"&&typeof l!="symbol"&&!!l,t.checked=f?t.checked:!!l,t.defaultChecked=!!l,s!=null&&typeof s!="function"&&typeof s!="symbol"&&typeof s!="boolean"&&(t.name=s),Ku(t)}function ku(t,e,a){e==="number"&&Ei(t.ownerDocument)===t||t.defaultValue===""+a||(t.defaultValue=""+a)}function Rl(t,e,a,l){if(t=t.options,e){e={};for(var n=0;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Pu=!1;if(oa)try{var Mn={};Object.defineProperty(Mn,"passive",{get:function(){Pu=!0}}),window.addEventListener("test",Mn,Mn),window.removeEventListener("test",Mn,Mn)}catch{Pu=!1}var Ca=null,ts=null,Ai=null;function qo(){if(Ai)return Ai;var t,e=ts,a=e.length,l,n="value"in Ca?Ca.value:Ca.textContent,i=n.length;for(t=0;t=Dn),Lo=" ",Vo=!1;function Zo(t,e){switch(t){case"keyup":return Ym.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Ko(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var jl=!1;function Xm(t,e){switch(t){case"compositionend":return Ko(e);case"keypress":return e.which!==32?null:(Vo=!0,Lo);case"textInput":return t=e.data,t===Lo&&Vo?null:t;default:return null}}function Lm(t,e){if(jl)return t==="compositionend"||!is&&Zo(t,e)?(t=qo(),Ai=ts=Ca=null,jl=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1=e)return{node:a,offset:e-t};t=l}t:{for(;a;){if(a.nextSibling){a=a.nextSibling;break t}a=a.parentNode}a=void 0}a=tr(a)}}function ar(t,e){return t&&e?t===e?!0:t&&t.nodeType===3?!1:e&&e.nodeType===3?ar(t,e.parentNode):"contains"in t?t.contains(e):t.compareDocumentPosition?!!(t.compareDocumentPosition(e)&16):!1:!1}function lr(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var e=Ei(t.document);e instanceof t.HTMLIFrameElement;){try{var a=typeof e.contentWindow.location.href=="string"}catch{a=!1}if(a)t=e.contentWindow;else break;e=Ei(t.document)}return e}function cs(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&(e==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||e==="textarea"||t.contentEditable==="true")}var $m=oa&&"documentMode"in document&&11>=document.documentMode,Ql=null,os=null,Un=null,rs=!1;function nr(t,e,a){var l=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;rs||Ql==null||Ql!==Ei(l)||(l=Ql,"selectionStart"in l&&cs(l)?l={start:l.selectionStart,end:l.selectionEnd}:(l=(l.ownerDocument&&l.ownerDocument.defaultView||window).getSelection(),l={anchorNode:l.anchorNode,anchorOffset:l.anchorOffset,focusNode:l.focusNode,focusOffset:l.focusOffset}),Un&&_n(Un,l)||(Un=l,l=pu(os,"onSelect"),0>=s,n-=s,ta=1<<32-ne(e)+n|a<tt?(rt=G,G=null):rt=G.sibling;var yt=x(g,G,p[tt],M);if(yt===null){G===null&&(G=rt);break}t&&G&&yt.alternate===null&&e(g,G),m=i(yt,m,tt),mt===null?V=yt:mt.sibling=yt,mt=yt,G=rt}if(tt===p.length)return a(g,G),ft&&fa(g,tt),V;if(G===null){for(;tttt?(rt=G,G=null):rt=G.sibling;var Ia=x(g,G,yt.value,M);if(Ia===null){G===null&&(G=rt);break}t&&G&&Ia.alternate===null&&e(g,G),m=i(Ia,m,tt),mt===null?V=Ia:mt.sibling=Ia,mt=Ia,G=rt}if(yt.done)return a(g,G),ft&&fa(g,tt),V;if(G===null){for(;!yt.done;tt++,yt=p.next())yt=w(g,yt.value,M),yt!==null&&(m=i(yt,m,tt),mt===null?V=yt:mt.sibling=yt,mt=yt);return ft&&fa(g,tt),V}for(G=l(G);!yt.done;tt++,yt=p.next())yt=z(G,g,tt,yt.value,M),yt!==null&&(t&&yt.alternate!==null&&G.delete(yt.key===null?tt:yt.key),m=i(yt,m,tt),mt===null?V=yt:mt.sibling=yt,mt=yt);return t&&G.forEach(function(gy){return e(g,gy)}),ft&&fa(g,tt),V}function Et(g,m,p,M){if(typeof p=="object"&&p!==null&&p.type===L&&p.key===null&&(p=p.props.children),typeof p=="object"&&p!==null){switch(p.$$typeof){case K:t:{for(var V=p.key;m!==null;){if(m.key===V){if(V=p.type,V===L){if(m.tag===7){a(g,m.sibling),M=n(m,p.props.children),M.return=g,g=M;break t}}else if(m.elementType===V||typeof V=="object"&&V!==null&&V.$$typeof===q&&vl(V)===m.type){a(g,m.sibling),M=n(m,p.props),Qn(M,p),M.return=g,g=M;break t}a(g,m);break}else e(g,m);m=m.sibling}p.type===L?(M=fl(p.props.children,g.mode,M,p.key),M.return=g,g=M):(M=Hi(p.type,p.key,p.props,null,g.mode,M),Qn(M,p),M.return=g,g=M)}return s(g);case B:t:{for(V=p.key;m!==null;){if(m.key===V)if(m.tag===4&&m.stateNode.containerInfo===p.containerInfo&&m.stateNode.implementation===p.implementation){a(g,m.sibling),M=n(m,p.children||[]),M.return=g,g=M;break t}else{a(g,m);break}else e(g,m);m=m.sibling}M=gs(p,g.mode,M),M.return=g,g=M}return s(g);case q:return p=vl(p),Et(g,m,p,M)}if(Bt(p))return j(g,m,p,M);if(Dt(p)){if(V=Dt(p),typeof V!="function")throw Error(r(150));return p=V.call(p),J(g,m,p,M)}if(typeof p.then=="function")return Et(g,m,Xi(p),M);if(p.$$typeof===st)return Et(g,m,ji(g,p),M);Li(g,p)}return typeof p=="string"&&p!==""||typeof p=="number"||typeof p=="bigint"?(p=""+p,m!==null&&m.tag===6?(a(g,m.sibling),M=n(m,p),M.return=g,g=M):(a(g,m),M=vs(p,g.mode,M),M.return=g,g=M),s(g)):a(g,m)}return function(g,m,p,M){try{jn=0;var V=Et(g,m,p,M);return Wl=null,V}catch(G){if(G===Fl||G===Yi)throw G;var mt=De(29,G,null,g.mode);return mt.lanes=M,mt.return=g,mt}finally{}}}var pl=Or(!0),wr=Or(!1),Ha=!1;function Ds(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Cs(t,e){t=t.updateQueue,e.updateQueue===t&&(e.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function Ba(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function qa(t,e,a){var l=t.updateQueue;if(l===null)return null;if(l=l.shared,(vt&2)!==0){var n=l.pending;return n===null?e.next=e:(e.next=n.next,n.next=e),l.pending=e,e=Ri(t),fr(t,null,a),e}return Ui(t,l,e,a),Ri(t)}function Yn(t,e,a){if(e=e.updateQueue,e!==null&&(e=e.shared,(a&4194048)!==0)){var l=e.lanes;l&=t.pendingLanes,a|=l,e.lanes=a,ye(t,a)}}function Ns(t,e){var a=t.updateQueue,l=t.alternate;if(l!==null&&(l=l.updateQueue,a===l)){var n=null,i=null;if(a=a.firstBaseUpdate,a!==null){do{var s={lane:a.lane,tag:a.tag,payload:a.payload,callback:null,next:null};i===null?n=i=s:i=i.next=s,a=a.next}while(a!==null);i===null?n=i=e:i=i.next=e}else n=i=e;a={baseState:l.baseState,firstBaseUpdate:n,lastBaseUpdate:i,shared:l.shared,callbacks:l.callbacks},t.updateQueue=a;return}t=a.lastBaseUpdate,t===null?a.firstBaseUpdate=e:t.next=e,a.lastBaseUpdate=e}var _s=!1;function Gn(){if(_s){var t=kl;if(t!==null)throw t}}function Xn(t,e,a,l){_s=!1;var n=t.updateQueue;Ha=!1;var i=n.firstBaseUpdate,s=n.lastBaseUpdate,f=n.shared.pending;if(f!==null){n.shared.pending=null;var d=f,b=d.next;d.next=null,s===null?i=b:s.next=b,s=d;var A=t.alternate;A!==null&&(A=A.updateQueue,f=A.lastBaseUpdate,f!==s&&(f===null?A.firstBaseUpdate=b:f.next=b,A.lastBaseUpdate=d))}if(i!==null){var w=n.baseState;s=0,A=b=d=null,f=i;do{var x=f.lane&-536870913,z=x!==f.lane;if(z?(ot&x)===x:(l&x)===x){x!==0&&x===Jl&&(_s=!0),A!==null&&(A=A.next={lane:0,tag:f.tag,payload:f.payload,callback:null,next:null});t:{var j=t,J=f;x=e;var Et=a;switch(J.tag){case 1:if(j=J.payload,typeof j=="function"){w=j.call(Et,w,x);break t}w=j;break t;case 3:j.flags=j.flags&-65537|128;case 0:if(j=J.payload,x=typeof j=="function"?j.call(Et,w,x):j,x==null)break t;w=h({},w,x);break t;case 2:Ha=!0}}x=f.callback,x!==null&&(t.flags|=64,z&&(t.flags|=8192),z=n.callbacks,z===null?n.callbacks=[x]:z.push(x))}else z={lane:x,tag:f.tag,payload:f.payload,callback:f.callback,next:null},A===null?(b=A=z,d=w):A=A.next=z,s|=x;if(f=f.next,f===null){if(f=n.shared.pending,f===null)break;z=f,f=z.next,z.next=null,n.lastBaseUpdate=z,n.shared.pending=null}}while(!0);A===null&&(d=w),n.baseState=d,n.firstBaseUpdate=b,n.lastBaseUpdate=A,i===null&&(n.shared.lanes=0),Xa|=s,t.lanes=s,t.memoizedState=w}}function Dr(t,e){if(typeof t!="function")throw Error(r(191,t));t.call(e)}function Cr(t,e){var a=t.callbacks;if(a!==null)for(t.callbacks=null,t=0;ti?i:8;var s=S.T,f={};S.T=f,$s(t,!1,e,a);try{var d=n(),b=S.S;if(b!==null&&b(f,d),d!==null&&typeof d=="object"&&typeof d.then=="function"){var A=u0(d,l);Zn(t,e,A,Re(t))}else Zn(t,e,l,Re(t))}catch(w){Zn(t,e,{then:function(){},status:"rejected",reason:w},Re())}finally{N.p=i,s!==null&&f.types!==null&&(s.types=f.types),S.T=s}}function d0(){}function Fs(t,e,a,l){if(t.tag!==5)throw Error(r(476));var n=of(t).queue;cf(t,n,e,D,a===null?d0:function(){return rf(t),a(l)})}function of(t){var e=t.memoizedState;if(e!==null)return e;e={memoizedState:D,baseState:D,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ya,lastRenderedState:D},next:null};var a={};return e.next={memoizedState:a,baseState:a,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ya,lastRenderedState:a},next:null},t.memoizedState=e,t=t.alternate,t!==null&&(t.memoizedState=e),e}function rf(t){var e=of(t);e.next===null&&(e=t.alternate.memoizedState),Zn(t,e.next.queue,{},Re())}function Ws(){return ee(ci)}function ff(){return Yt().memoizedState}function df(){return Yt().memoizedState}function h0(t){for(var e=t.return;e!==null;){switch(e.tag){case 24:case 3:var a=Re();t=Ba(a);var l=qa(e,t,a);l!==null&&(Ee(l,e,a),Yn(l,e,a)),e={cache:As()},t.payload=e;return}e=e.return}}function m0(t,e,a){var l=Re();a={lane:l,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Pi(t)?mf(e,a):(a=ms(t,e,a,l),a!==null&&(Ee(a,t,l),yf(a,e,l)))}function hf(t,e,a){var l=Re();Zn(t,e,a,l)}function Zn(t,e,a,l){var n={lane:l,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null};if(Pi(t))mf(e,n);else{var i=t.alternate;if(t.lanes===0&&(i===null||i.lanes===0)&&(i=e.lastRenderedReducer,i!==null))try{var s=e.lastRenderedState,f=i(s,a);if(n.hasEagerState=!0,n.eagerState=f,we(f,s))return Ui(t,e,n,0),Mt===null&&_i(),!1}catch{}finally{}if(a=ms(t,e,n,l),a!==null)return Ee(a,t,l),yf(a,e,l),!0}return!1}function $s(t,e,a,l){if(l={lane:2,revertLane:Dc(),gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},Pi(t)){if(e)throw Error(r(479))}else e=ms(t,a,l,2),e!==null&&Ee(e,t,2)}function Pi(t){var e=t.alternate;return t===$||e!==null&&e===$}function mf(t,e){Il=Ki=!0;var a=t.pending;a===null?e.next=e:(e.next=a.next,a.next=e),t.pending=e}function yf(t,e,a){if((a&4194048)!==0){var l=e.lanes;l&=t.pendingLanes,a|=l,e.lanes=a,ye(t,a)}}var Kn={readContext:ee,use:Fi,useCallback:qt,useContext:qt,useEffect:qt,useImperativeHandle:qt,useLayoutEffect:qt,useInsertionEffect:qt,useMemo:qt,useReducer:qt,useRef:qt,useState:qt,useDebugValue:qt,useDeferredValue:qt,useTransition:qt,useSyncExternalStore:qt,useId:qt,useHostTransitionStatus:qt,useFormState:qt,useActionState:qt,useOptimistic:qt,useMemoCache:qt,useCacheRefresh:qt};Kn.useEffectEvent=qt;var vf={readContext:ee,use:Fi,useCallback:function(t,e){return fe().memoizedState=[t,e===void 0?null:e],t},useContext:ee,useEffect:Ir,useImperativeHandle:function(t,e,a){a=a!=null?a.concat([t]):null,$i(4194308,4,af.bind(null,e,t),a)},useLayoutEffect:function(t,e){return $i(4194308,4,t,e)},useInsertionEffect:function(t,e){$i(4,2,t,e)},useMemo:function(t,e){var a=fe();e=e===void 0?null:e;var l=t();if(bl){Ke(!0);try{t()}finally{Ke(!1)}}return a.memoizedState=[l,e],l},useReducer:function(t,e,a){var l=fe();if(a!==void 0){var n=a(e);if(bl){Ke(!0);try{a(e)}finally{Ke(!1)}}}else n=e;return l.memoizedState=l.baseState=n,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:n},l.queue=t,t=t.dispatch=m0.bind(null,$,t),[l.memoizedState,t]},useRef:function(t){var e=fe();return t={current:t},e.memoizedState=t},useState:function(t){t=Vs(t);var e=t.queue,a=hf.bind(null,$,e);return e.dispatch=a,[t.memoizedState,a]},useDebugValue:Js,useDeferredValue:function(t,e){var a=fe();return ks(a,t,e)},useTransition:function(){var t=Vs(!1);return t=cf.bind(null,$,t.queue,!0,!1),fe().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,e,a){var l=$,n=fe();if(ft){if(a===void 0)throw Error(r(407));a=a()}else{if(a=e(),Mt===null)throw Error(r(349));(ot&127)!==0||Br(l,e,a)}n.memoizedState=a;var i={value:a,getSnapshot:e};return n.queue=i,Ir(jr.bind(null,l,i,t),[t]),l.flags|=2048,tn(9,{destroy:void 0},qr.bind(null,l,i,a,e),null),a},useId:function(){var t=fe(),e=Mt.identifierPrefix;if(ft){var a=ea,l=ta;a=(l&~(1<<32-ne(l)-1)).toString(32)+a,e="_"+e+"R_"+a,a=Ji++,0<\/script>",i=i.removeChild(i.firstChild);break;case"select":i=typeof l.is=="string"?s.createElement("select",{is:l.is}):s.createElement("select"),l.multiple?i.multiple=!0:l.size&&(i.size=l.size);break;default:i=typeof l.is=="string"?s.createElement(n,{is:l.is}):s.createElement(n)}}i[Pt]=e,i[ge]=l;t:for(s=e.child;s!==null;){if(s.tag===5||s.tag===6)i.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===e)break t;for(;s.sibling===null;){if(s.return===null||s.return===e)break t;s=s.return}s.sibling.return=s.return,s=s.sibling}e.stateNode=i;t:switch(le(i,n,l),n){case"button":case"input":case"select":case"textarea":l=!!l.autoFocus;break t;case"img":l=!0;break t;default:l=!1}l&&ga(e)}}return Nt(e),fc(e,e.type,t===null?null:t.memoizedProps,e.pendingProps,a),null;case 6:if(t&&e.stateNode!=null)t.memoizedProps!==l&&ga(e);else{if(typeof l!="string"&&e.stateNode===null)throw Error(r(166));if(t=_t.current,Zl(e)){if(t=e.stateNode,a=e.memoizedProps,l=null,n=te,n!==null)switch(n.tag){case 27:case 5:l=n.memoizedProps}t[Pt]=e,t=!!(t.nodeValue===a||l!==null&&l.suppressHydrationWarning===!0||Hd(t.nodeValue,a)),t||Ua(e,!0)}else t=bu(t).createTextNode(l),t[Pt]=e,e.stateNode=t}return Nt(e),null;case 31:if(a=e.memoizedState,t===null||t.memoizedState!==null){if(l=Zl(e),a!==null){if(t===null){if(!l)throw Error(r(318));if(t=e.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(r(557));t[Pt]=e}else dl(),(e.flags&128)===0&&(e.memoizedState=null),e.flags|=4;Nt(e),t=!1}else a=xs(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=a),t=!0;if(!t)return e.flags&256?(Ne(e),e):(Ne(e),null);if((e.flags&128)!==0)throw Error(r(558))}return Nt(e),null;case 13:if(l=e.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(n=Zl(e),l!==null&&l.dehydrated!==null){if(t===null){if(!n)throw Error(r(318));if(n=e.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(r(317));n[Pt]=e}else dl(),(e.flags&128)===0&&(e.memoizedState=null),e.flags|=4;Nt(e),n=!1}else n=xs(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=n),n=!0;if(!n)return e.flags&256?(Ne(e),e):(Ne(e),null)}return Ne(e),(e.flags&128)!==0?(e.lanes=a,e):(a=l!==null,t=t!==null&&t.memoizedState!==null,a&&(l=e.child,n=null,l.alternate!==null&&l.alternate.memoizedState!==null&&l.alternate.memoizedState.cachePool!==null&&(n=l.alternate.memoizedState.cachePool.pool),i=null,l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(i=l.memoizedState.cachePool.pool),i!==n&&(l.flags|=2048)),a!==t&&a&&(e.child.flags|=8192),nu(e,e.updateQueue),Nt(e),null);case 4:return Ft(),t===null&&Uc(e.stateNode.containerInfo),Nt(e),null;case 10:return ha(e.type),Nt(e),null;case 19:if(dt(Qt),l=e.memoizedState,l===null)return Nt(e),null;if(n=(e.flags&128)!==0,i=l.rendering,i===null)if(n)kn(l,!1);else{if(jt!==0||t!==null&&(t.flags&128)!==0)for(t=e.child;t!==null;){if(i=Zi(t),i!==null){for(e.flags|=128,kn(l,!1),t=i.updateQueue,e.updateQueue=t,nu(e,t),e.subtreeFlags=0,t=a,a=e.child;a!==null;)dr(a,t),a=a.sibling;return U(Qt,Qt.current&1|2),ft&&fa(e,l.treeForkCount),e.child}t=t.sibling}l.tail!==null&&oe()>ou&&(e.flags|=128,n=!0,kn(l,!1),e.lanes=4194304)}else{if(!n)if(t=Zi(i),t!==null){if(e.flags|=128,n=!0,t=t.updateQueue,e.updateQueue=t,nu(e,t),kn(l,!0),l.tail===null&&l.tailMode==="hidden"&&!i.alternate&&!ft)return Nt(e),null}else 2*oe()-l.renderingStartTime>ou&&a!==536870912&&(e.flags|=128,n=!0,kn(l,!1),e.lanes=4194304);l.isBackwards?(i.sibling=e.child,e.child=i):(t=l.last,t!==null?t.sibling=i:e.child=i,l.last=i)}return l.tail!==null?(t=l.tail,l.rendering=t,l.tail=t.sibling,l.renderingStartTime=oe(),t.sibling=null,a=Qt.current,U(Qt,n?a&1|2:a&1),ft&&fa(e,l.treeForkCount),t):(Nt(e),null);case 22:case 23:return Ne(e),Rs(),l=e.memoizedState!==null,t!==null?t.memoizedState!==null!==l&&(e.flags|=8192):l&&(e.flags|=8192),l?(a&536870912)!==0&&(e.flags&128)===0&&(Nt(e),e.subtreeFlags&6&&(e.flags|=8192)):Nt(e),a=e.updateQueue,a!==null&&nu(e,a.retryQueue),a=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(a=t.memoizedState.cachePool.pool),l=null,e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(l=e.memoizedState.cachePool.pool),l!==a&&(e.flags|=2048),t!==null&&dt(yl),null;case 24:return a=null,t!==null&&(a=t.memoizedState.cache),e.memoizedState.cache!==a&&(e.flags|=2048),ha(Xt),Nt(e),null;case 25:return null;case 30:return null}throw Error(r(156,e.tag))}function b0(t,e){switch(bs(e),e.tag){case 1:return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 3:return ha(Xt),Ft(),t=e.flags,(t&65536)!==0&&(t&128)===0?(e.flags=t&-65537|128,e):null;case 26:case 27:case 5:return Me(e),null;case 31:if(e.memoizedState!==null){if(Ne(e),e.alternate===null)throw Error(r(340));dl()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 13:if(Ne(e),t=e.memoizedState,t!==null&&t.dehydrated!==null){if(e.alternate===null)throw Error(r(340));dl()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 19:return dt(Qt),null;case 4:return Ft(),null;case 10:return ha(e.type),null;case 22:case 23:return Ne(e),Rs(),t!==null&&dt(yl),t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 24:return ha(Xt),null;case 25:return null;default:return null}}function Yf(t,e){switch(bs(e),e.tag){case 3:ha(Xt),Ft();break;case 26:case 27:case 5:Me(e);break;case 4:Ft();break;case 31:e.memoizedState!==null&&Ne(e);break;case 13:Ne(e);break;case 19:dt(Qt);break;case 10:ha(e.type);break;case 22:case 23:Ne(e),Rs(),t!==null&&dt(yl);break;case 24:ha(Xt)}}function Fn(t,e){try{var a=e.updateQueue,l=a!==null?a.lastEffect:null;if(l!==null){var n=l.next;a=n;do{if((a.tag&t)===t){l=void 0;var i=a.create,s=a.inst;l=i(),s.destroy=l}a=a.next}while(a!==n)}}catch(f){bt(e,e.return,f)}}function Ya(t,e,a){try{var l=e.updateQueue,n=l!==null?l.lastEffect:null;if(n!==null){var i=n.next;l=i;do{if((l.tag&t)===t){var s=l.inst,f=s.destroy;if(f!==void 0){s.destroy=void 0,n=e;var d=a,b=f;try{b()}catch(A){bt(n,d,A)}}}l=l.next}while(l!==i)}}catch(A){bt(e,e.return,A)}}function Gf(t){var e=t.updateQueue;if(e!==null){var a=t.stateNode;try{Cr(e,a)}catch(l){bt(t,t.return,l)}}}function Xf(t,e,a){a.props=Sl(t.type,t.memoizedProps),a.state=t.memoizedState;try{a.componentWillUnmount()}catch(l){bt(t,e,l)}}function Wn(t,e){try{var a=t.ref;if(a!==null){switch(t.tag){case 26:case 27:case 5:var l=t.stateNode;break;case 30:l=t.stateNode;break;default:l=t.stateNode}typeof a=="function"?t.refCleanup=a(l):a.current=l}}catch(n){bt(t,e,n)}}function aa(t,e){var a=t.ref,l=t.refCleanup;if(a!==null)if(typeof l=="function")try{l()}catch(n){bt(t,e,n)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof a=="function")try{a(null)}catch(n){bt(t,e,n)}else a.current=null}function Lf(t){var e=t.type,a=t.memoizedProps,l=t.stateNode;try{t:switch(e){case"button":case"input":case"select":case"textarea":a.autoFocus&&l.focus();break t;case"img":a.src?l.src=a.src:a.srcSet&&(l.srcset=a.srcSet)}}catch(n){bt(t,t.return,n)}}function dc(t,e,a){try{var l=t.stateNode;G0(l,t.type,a,e),l[ge]=e}catch(n){bt(t,t.return,n)}}function Vf(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&Ja(t.type)||t.tag===4}function hc(t){t:for(;;){for(;t.sibling===null;){if(t.return===null||Vf(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&Ja(t.type)||t.flags&2||t.child===null||t.tag===4)continue t;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function mc(t,e,a){var l=t.tag;if(l===5||l===6)t=t.stateNode,e?(a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a).insertBefore(t,e):(e=a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a,e.appendChild(t),a=a._reactRootContainer,a!=null||e.onclick!==null||(e.onclick=ca));else if(l!==4&&(l===27&&Ja(t.type)&&(a=t.stateNode,e=null),t=t.child,t!==null))for(mc(t,e,a),t=t.sibling;t!==null;)mc(t,e,a),t=t.sibling}function iu(t,e,a){var l=t.tag;if(l===5||l===6)t=t.stateNode,e?a.insertBefore(t,e):a.appendChild(t);else if(l!==4&&(l===27&&Ja(t.type)&&(a=t.stateNode),t=t.child,t!==null))for(iu(t,e,a),t=t.sibling;t!==null;)iu(t,e,a),t=t.sibling}function Zf(t){var e=t.stateNode,a=t.memoizedProps;try{for(var l=t.type,n=e.attributes;n.length;)e.removeAttributeNode(n[0]);le(e,l,a),e[Pt]=t,e[ge]=a}catch(i){bt(t,t.return,i)}}var pa=!1,Zt=!1,yc=!1,Kf=typeof WeakSet=="function"?WeakSet:Set,It=null;function S0(t,e){if(t=t.containerInfo,Bc=Mu,t=lr(t),cs(t)){if("selectionStart"in t)var a={start:t.selectionStart,end:t.selectionEnd};else t:{a=(a=t.ownerDocument)&&a.defaultView||window;var l=a.getSelection&&a.getSelection();if(l&&l.rangeCount!==0){a=l.anchorNode;var n=l.anchorOffset,i=l.focusNode;l=l.focusOffset;try{a.nodeType,i.nodeType}catch{a=null;break t}var s=0,f=-1,d=-1,b=0,A=0,w=t,x=null;e:for(;;){for(var z;w!==a||n!==0&&w.nodeType!==3||(f=s+n),w!==i||l!==0&&w.nodeType!==3||(d=s+l),w.nodeType===3&&(s+=w.nodeValue.length),(z=w.firstChild)!==null;)x=w,w=z;for(;;){if(w===t)break e;if(x===a&&++b===n&&(f=s),x===i&&++A===l&&(d=s),(z=w.nextSibling)!==null)break;w=x,x=w.parentNode}w=z}a=f===-1||d===-1?null:{start:f,end:d}}else a=null}a=a||{start:0,end:0}}else a=null;for(qc={focusedElem:t,selectionRange:a},Mu=!1,It=e;It!==null;)if(e=It,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,It=t;else for(;It!==null;){switch(e=It,i=e.alternate,t=e.flags,e.tag){case 0:if((t&4)!==0&&(t=e.updateQueue,t=t!==null?t.events:null,t!==null))for(a=0;a title"))),le(i,l,a),i[Pt]=t,$t(i),l=i;break t;case"link":var s=Id("link","href",n).get(l+(a.href||""));if(s){for(var f=0;fEt&&(s=Et,Et=J,J=s);var g=er(f,J),m=er(f,Et);if(g&&m&&(z.rangeCount!==1||z.anchorNode!==g.node||z.anchorOffset!==g.offset||z.focusNode!==m.node||z.focusOffset!==m.offset)){var p=w.createRange();p.setStart(g.node,g.offset),z.removeAllRanges(),J>Et?(z.addRange(p),z.extend(m.node,m.offset)):(p.setEnd(m.node,m.offset),z.addRange(p))}}}}for(w=[],z=f;z=z.parentNode;)z.nodeType===1&&w.push({element:z,left:z.scrollLeft,top:z.scrollTop});for(typeof f.focus=="function"&&f.focus(),f=0;fa?32:a,S.T=null,a=zc,zc=null;var i=Va,s=Ea;if(Kt=0,un=Va=null,Ea=0,(vt&6)!==0)throw Error(r(331));var f=vt;if(vt|=4,ld(i.current),td(i,i.current,s,a),vt=f,ai(0,!1),re&&typeof re.onPostCommitFiberRoot=="function")try{re.onPostCommitFiberRoot(ll,i)}catch{}return!0}finally{N.p=n,S.T=l,xd(t,e)}}function Ed(t,e,a){e=je(a,e),e=ec(t.stateNode,e,2),t=qa(t,e,2),t!==null&&(Ht(t,2),la(t))}function bt(t,e,a){if(t.tag===3)Ed(t,t,a);else for(;e!==null;){if(e.tag===3){Ed(e,t,a);break}else if(e.tag===1){var l=e.stateNode;if(typeof e.type.getDerivedStateFromError=="function"||typeof l.componentDidCatch=="function"&&(La===null||!La.has(l))){t=je(a,t),a=Tf(2),l=qa(e,a,2),l!==null&&(Af(a,l,e,t),Ht(l,2),la(l));break}}e=e.return}}function Mc(t,e,a){var l=t.pingCache;if(l===null){l=t.pingCache=new E0;var n=new Set;l.set(e,n)}else n=l.get(e),n===void 0&&(n=new Set,l.set(e,n));n.has(a)||(pc=!0,n.add(a),t=w0.bind(null,t,e,a),e.then(t,t))}function w0(t,e,a){var l=t.pingCache;l!==null&&l.delete(e),t.pingedLanes|=t.suspendedLanes&a,t.warmLanes&=~a,Mt===t&&(ot&a)===a&&(jt===4||jt===3&&(ot&62914560)===ot&&300>oe()-cu?(vt&2)===0&&sn(t,0):bc|=a,nn===ot&&(nn=0)),la(t)}function Td(t,e){e===0&&(e=ie()),t=rl(t,e),t!==null&&(Ht(t,e),la(t))}function D0(t){var e=t.memoizedState,a=0;e!==null&&(a=e.retryLane),Td(t,a)}function C0(t,e){var a=0;switch(t.tag){case 31:case 13:var l=t.stateNode,n=t.memoizedState;n!==null&&(a=n.retryLane);break;case 19:l=t.stateNode;break;case 22:l=t.stateNode._retryCache;break;default:throw Error(r(314))}l!==null&&l.delete(e),Td(t,a)}function N0(t,e){return bn(t,e)}var yu=null,on=null,Oc=!1,vu=!1,wc=!1,Ka=0;function la(t){t!==on&&t.next===null&&(on===null?yu=on=t:on=on.next=t),vu=!0,Oc||(Oc=!0,U0())}function ai(t,e){if(!wc&&vu){wc=!0;do for(var a=!1,l=yu;l!==null;){if(t!==0){var n=l.pendingLanes;if(n===0)var i=0;else{var s=l.suspendedLanes,f=l.pingedLanes;i=(1<<31-ne(42|t)+1)-1,i&=n&~(s&~f),i=i&201326741?i&201326741|1:i?i|2:0}i!==0&&(a=!0,wd(l,i))}else i=ot,i=F(l,l===Mt?i:0,l.cancelPendingCommit!==null||l.timeoutHandle!==-1),(i&3)===0||Ut(l,i)||(a=!0,wd(l,i));l=l.next}while(a);wc=!1}}function _0(){Ad()}function Ad(){vu=Oc=!1;var t=0;Ka!==0&&L0()&&(t=Ka);for(var e=oe(),a=null,l=yu;l!==null;){var n=l.next,i=Md(l,e);i===0?(l.next=null,a===null?yu=n:a.next=n,n===null&&(on=a)):(a=l,(t!==0||(i&3)!==0)&&(vu=!0)),l=n}Kt!==0&&Kt!==5||ai(t),Ka!==0&&(Ka=0)}function Md(t,e){for(var a=t.suspendedLanes,l=t.pingedLanes,n=t.expirationTimes,i=t.pendingLanes&-62914561;0f)break;var A=d.transferSize,w=d.initiatorType;A&&Bd(w)&&(d=d.responseEnd,s+=A*(d"u"?null:document;function kd(t,e,a){var l=rn;if(l&&typeof e=="string"&&e){var n=Be(e);n='link[rel="'+t+'"][href="'+n+'"]',typeof a=="string"&&(n+='[crossorigin="'+a+'"]'),Jd.has(n)||(Jd.add(n),t={rel:t,crossOrigin:a,href:e},l.querySelector(n)===null&&(e=l.createElement("link"),le(e,"link",t),$t(e),l.head.appendChild(e)))}}function I0(t){Ta.D(t),kd("dns-prefetch",t,null)}function P0(t,e){Ta.C(t,e),kd("preconnect",t,e)}function ty(t,e,a){Ta.L(t,e,a);var l=rn;if(l&&t&&e){var n='link[rel="preload"][as="'+Be(e)+'"]';e==="image"&&a&&a.imageSrcSet?(n+='[imagesrcset="'+Be(a.imageSrcSet)+'"]',typeof a.imageSizes=="string"&&(n+='[imagesizes="'+Be(a.imageSizes)+'"]')):n+='[href="'+Be(t)+'"]';var i=n;switch(e){case"style":i=fn(t);break;case"script":i=dn(t)}Ve.has(i)||(t=h({rel:"preload",href:e==="image"&&a&&a.imageSrcSet?void 0:t,as:e},a),Ve.set(i,t),l.querySelector(n)!==null||e==="style"&&l.querySelector(ui(i))||e==="script"&&l.querySelector(si(i))||(e=l.createElement("link"),le(e,"link",t),$t(e),l.head.appendChild(e)))}}function ey(t,e){Ta.m(t,e);var a=rn;if(a&&t){var l=e&&typeof e.as=="string"?e.as:"script",n='link[rel="modulepreload"][as="'+Be(l)+'"][href="'+Be(t)+'"]',i=n;switch(l){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":i=dn(t)}if(!Ve.has(i)&&(t=h({rel:"modulepreload",href:t},e),Ve.set(i,t),a.querySelector(n)===null)){switch(l){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(a.querySelector(si(i)))return}l=a.createElement("link"),le(l,"link",t),$t(l),a.head.appendChild(l)}}}function ay(t,e,a){Ta.S(t,e,a);var l=rn;if(l&&t){var n=_l(l).hoistableStyles,i=fn(t);e=e||"default";var s=n.get(i);if(!s){var f={loading:0,preload:null};if(s=l.querySelector(ui(i)))f.loading=5;else{t=h({rel:"stylesheet",href:t,"data-precedence":e},a),(a=Ve.get(i))&&Vc(t,a);var d=s=l.createElement("link");$t(d),le(d,"link",t),d._p=new Promise(function(b,A){d.onload=b,d.onerror=A}),d.addEventListener("load",function(){f.loading|=1}),d.addEventListener("error",function(){f.loading|=2}),f.loading|=4,xu(s,e,l)}s={type:"stylesheet",instance:s,count:1,state:f},n.set(i,s)}}}function ly(t,e){Ta.X(t,e);var a=rn;if(a&&t){var l=_l(a).hoistableScripts,n=dn(t),i=l.get(n);i||(i=a.querySelector(si(n)),i||(t=h({src:t,async:!0},e),(e=Ve.get(n))&&Zc(t,e),i=a.createElement("script"),$t(i),le(i,"link",t),a.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},l.set(n,i))}}function ny(t,e){Ta.M(t,e);var a=rn;if(a&&t){var l=_l(a).hoistableScripts,n=dn(t),i=l.get(n);i||(i=a.querySelector(si(n)),i||(t=h({src:t,async:!0,type:"module"},e),(e=Ve.get(n))&&Zc(t,e),i=a.createElement("script"),$t(i),le(i,"link",t),a.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},l.set(n,i))}}function Fd(t,e,a,l){var n=(n=_t.current)?Su(n):null;if(!n)throw Error(r(446));switch(t){case"meta":case"title":return null;case"style":return typeof a.precedence=="string"&&typeof a.href=="string"?(e=fn(a.href),a=_l(n).hoistableStyles,l=a.get(e),l||(l={type:"style",instance:null,count:0,state:null},a.set(e,l)),l):{type:"void",instance:null,count:0,state:null};case"link":if(a.rel==="stylesheet"&&typeof a.href=="string"&&typeof a.precedence=="string"){t=fn(a.href);var i=_l(n).hoistableStyles,s=i.get(t);if(s||(n=n.ownerDocument||n,s={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},i.set(t,s),(i=n.querySelector(ui(t)))&&!i._p&&(s.instance=i,s.state.loading=5),Ve.has(t)||(a={rel:"preload",as:"style",href:a.href,crossOrigin:a.crossOrigin,integrity:a.integrity,media:a.media,hrefLang:a.hrefLang,referrerPolicy:a.referrerPolicy},Ve.set(t,a),i||iy(n,t,a,s.state))),e&&l===null)throw Error(r(528,""));return s}if(e&&l!==null)throw Error(r(529,""));return null;case"script":return e=a.async,a=a.src,typeof a=="string"&&e&&typeof e!="function"&&typeof e!="symbol"?(e=dn(a),a=_l(n).hoistableScripts,l=a.get(e),l||(l={type:"script",instance:null,count:0,state:null},a.set(e,l)),l):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,t))}}function fn(t){return'href="'+Be(t)+'"'}function ui(t){return'link[rel="stylesheet"]['+t+"]"}function Wd(t){return h({},t,{"data-precedence":t.precedence,precedence:null})}function iy(t,e,a,l){t.querySelector('link[rel="preload"][as="style"]['+e+"]")?l.loading=1:(e=t.createElement("link"),l.preload=e,e.addEventListener("load",function(){return l.loading|=1}),e.addEventListener("error",function(){return l.loading|=2}),le(e,"link",a),$t(e),t.head.appendChild(e))}function dn(t){return'[src="'+Be(t)+'"]'}function si(t){return"script[async]"+t}function $d(t,e,a){if(e.count++,e.instance===null)switch(e.type){case"style":var l=t.querySelector('style[data-href~="'+Be(a.href)+'"]');if(l)return e.instance=l,$t(l),l;var n=h({},a,{"data-href":a.href,"data-precedence":a.precedence,href:null,precedence:null});return l=(t.ownerDocument||t).createElement("style"),$t(l),le(l,"style",n),xu(l,a.precedence,t),e.instance=l;case"stylesheet":n=fn(a.href);var i=t.querySelector(ui(n));if(i)return e.state.loading|=4,e.instance=i,$t(i),i;l=Wd(a),(n=Ve.get(n))&&Vc(l,n),i=(t.ownerDocument||t).createElement("link"),$t(i);var s=i;return s._p=new Promise(function(f,d){s.onload=f,s.onerror=d}),le(i,"link",l),e.state.loading|=4,xu(i,a.precedence,t),e.instance=i;case"script":return i=dn(a.src),(n=t.querySelector(si(i)))?(e.instance=n,$t(n),n):(l=a,(n=Ve.get(i))&&(l=h({},a),Zc(l,n)),t=t.ownerDocument||t,n=t.createElement("script"),$t(n),le(n,"link",l),t.head.appendChild(n),e.instance=n);case"void":return null;default:throw Error(r(443,e.type))}else e.type==="stylesheet"&&(e.state.loading&4)===0&&(l=e.instance,e.state.loading|=4,xu(l,a.precedence,t));return e.instance}function xu(t,e,a){for(var l=a.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=l.length?l[l.length-1]:null,i=n,s=0;s title"):null)}function uy(t,e,a){if(a===1||e.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof e.precedence!="string"||typeof e.href!="string"||e.href==="")break;return!0;case"link":if(typeof e.rel!="string"||typeof e.href!="string"||e.href===""||e.onLoad||e.onError)break;switch(e.rel){case"stylesheet":return t=e.disabled,typeof e.precedence=="string"&&t==null;default:return!0}case"script":if(e.async&&typeof e.async!="function"&&typeof e.async!="symbol"&&!e.onLoad&&!e.onError&&e.src&&typeof e.src=="string")return!0}return!1}function th(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function sy(t,e,a,l){if(a.type==="stylesheet"&&(typeof l.media!="string"||matchMedia(l.media).matches!==!1)&&(a.state.loading&4)===0){if(a.instance===null){var n=fn(l.href),i=e.querySelector(ui(n));if(i){e=i._p,e!==null&&typeof e=="object"&&typeof e.then=="function"&&(t.count++,t=Eu.bind(t),e.then(t,t)),a.state.loading|=4,a.instance=i,$t(i);return}i=e.ownerDocument||e,l=Wd(l),(n=Ve.get(n))&&Vc(l,n),i=i.createElement("link"),$t(i);var s=i;s._p=new Promise(function(f,d){s.onload=f,s.onerror=d}),le(i,"link",l),a.instance=i}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(a,e),(e=a.state.preload)&&(a.state.loading&3)===0&&(t.count++,a=Eu.bind(t),e.addEventListener("load",a),e.addEventListener("error",a))}}var Kc=0;function cy(t,e){return t.stylesheets&&t.count===0&&Au(t,t.stylesheets),0Kc?50:800)+e);return t.unsuspend=a,function(){t.unsuspend=null,clearTimeout(l),clearTimeout(n)}}:null}function Eu(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Au(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var Tu=null;function Au(t,e){t.stylesheets=null,t.unsuspend!==null&&(t.count++,Tu=new Map,e.forEach(oy,t),Tu=null,Eu.call(t))}function oy(t,e){if(!(e.state.loading&4)){var a=Tu.get(t);if(a)var l=a.get(null);else{a=new Map,Tu.set(t,a);for(var n=t.querySelectorAll("link[data-precedence],style[data-precedence]"),i=0;i"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(u)}catch(c){console.error(c)}}return u(),to.exports=Dy(),to.exports}var Ny=Cy(),Qu=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(u){return this.listeners.add(u),this.onSubscribe(),()=>{this.listeners.delete(u),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}},_y={setTimeout:(u,c)=>setTimeout(u,c),clearTimeout:u=>clearTimeout(u),setInterval:(u,c)=>setInterval(u,c),clearInterval:u=>clearInterval(u)},Uy=class{#t=_y;#e=!1;setTimeoutProvider(u){this.#t=u}setTimeout(u,c){return this.#t.setTimeout(u,c)}clearTimeout(u){this.#t.clearTimeout(u)}setInterval(u,c){return this.#t.setInterval(u,c)}clearInterval(u){this.#t.clearInterval(u)}},uo=new Uy;function Ry(u){setTimeout(u,0)}var Yu=typeof window>"u"||"Deno"in globalThis;function $e(){}function Hy(u,c){return typeof u=="function"?u(c):u}function By(u){return typeof u=="number"&&u>=0&&u!==1/0}function qy(u,c){return Math.max(u+(c||0)-Date.now(),0)}function so(u,c){return typeof u=="function"?u(c):u}function jy(u,c){return typeof u=="function"?u(c):u}function xh(u,c){const{type:o="all",exact:r,fetchStatus:y,predicate:v,queryKey:T,stale:E}=u;if(T){if(r){if(c.queryHash!==po(T,c.options))return!1}else if(!vi(c.queryKey,T))return!1}if(o!=="all"){const O=c.isActive();if(o==="active"&&!O||o==="inactive"&&O)return!1}return!(typeof E=="boolean"&&c.isStale()!==E||y&&y!==c.state.fetchStatus||v&&!v(c))}function zh(u,c){const{exact:o,status:r,predicate:y,mutationKey:v}=u;if(v){if(!c.options.mutationKey)return!1;if(o){if(yi(c.options.mutationKey)!==yi(v))return!1}else if(!vi(c.options.mutationKey,v))return!1}return!(r&&c.state.status!==r||y&&!y(c))}function po(u,c){return(c?.queryKeyHashFn||yi)(u)}function yi(u){return JSON.stringify(u,(c,o)=>co(o)?Object.keys(o).sort().reduce((r,y)=>(r[y]=o[y],r),{}):o)}function vi(u,c){return u===c?!0:typeof u!=typeof c?!1:u&&c&&typeof u=="object"&&typeof c=="object"?Object.keys(c).every(o=>vi(u[o],c[o])):!1}var Qy=Object.prototype.hasOwnProperty;function Gh(u,c){if(u===c)return u;const o=Eh(u)&&Eh(c);if(!o&&!(co(u)&&co(c)))return c;const y=(o?u:Object.keys(u)).length,v=o?c:Object.keys(c),T=v.length,E=o?new Array(T):{};let O=0;for(let C=0;C{uo.setTimeout(c,u)})}function Gy(u,c,o){return typeof o.structuralSharing=="function"?o.structuralSharing(u,c):o.structuralSharing!==!1?Gh(u,c):c}function Xy(u,c,o=0){const r=[...u,c];return o&&r.length>o?r.slice(1):r}function Ly(u,c,o=0){const r=[c,...u];return o&&r.length>o?r.slice(0,-1):r}var bo=Symbol();function Xh(u,c){return!u.queryFn&&c?.initialPromise?()=>c.initialPromise:!u.queryFn||u.queryFn===bo?()=>Promise.reject(new Error(`Missing queryFn: '${u.queryHash}'`)):u.queryFn}var Vy=class extends Qu{#t;#e;#a;constructor(){super(),this.#a=u=>{if(!Yu&&window.addEventListener){const c=()=>u();return window.addEventListener("visibilitychange",c,!1),()=>{window.removeEventListener("visibilitychange",c)}}}}onSubscribe(){this.#e||this.setEventListener(this.#a)}onUnsubscribe(){this.hasListeners()||(this.#e?.(),this.#e=void 0)}setEventListener(u){this.#a=u,this.#e?.(),this.#e=u(c=>{typeof c=="boolean"?this.setFocused(c):this.onFocus()})}setFocused(u){this.#t!==u&&(this.#t=u,this.onFocus())}onFocus(){const u=this.isFocused();this.listeners.forEach(c=>{c(u)})}isFocused(){return typeof this.#t=="boolean"?this.#t:globalThis.document?.visibilityState!=="hidden"}},Lh=new Vy;function Zy(){let u,c;const o=new Promise((y,v)=>{u=y,c=v});o.status="pending",o.catch(()=>{});function r(y){Object.assign(o,y),delete o.resolve,delete o.reject}return o.resolve=y=>{r({status:"fulfilled",value:y}),u(y)},o.reject=y=>{r({status:"rejected",reason:y}),c(y)},o}var Ky=Ry;function Jy(){let u=[],c=0,o=E=>{E()},r=E=>{E()},y=Ky;const v=E=>{c?u.push(E):y(()=>{o(E)})},T=()=>{const E=u;u=[],E.length&&y(()=>{r(()=>{E.forEach(O=>{o(O)})})})};return{batch:E=>{let O;c++;try{O=E()}finally{c--,c||T()}return O},batchCalls:E=>(...O)=>{v(()=>{E(...O)})},schedule:v,setNotifyFunction:E=>{o=E},setBatchNotifyFunction:E=>{r=E},setScheduler:E=>{y=E}}}var de=Jy(),ky=class extends Qu{#t=!0;#e;#a;constructor(){super(),this.#a=u=>{if(!Yu&&window.addEventListener){const c=()=>u(!0),o=()=>u(!1);return window.addEventListener("online",c,!1),window.addEventListener("offline",o,!1),()=>{window.removeEventListener("online",c),window.removeEventListener("offline",o)}}}}onSubscribe(){this.#e||this.setEventListener(this.#a)}onUnsubscribe(){this.hasListeners()||(this.#e?.(),this.#e=void 0)}setEventListener(u){this.#a=u,this.#e?.(),this.#e=u(this.setOnline.bind(this))}setOnline(u){this.#t!==u&&(this.#t=u,this.listeners.forEach(o=>{o(u)}))}isOnline(){return this.#t}},qu=new ky;function Fy(u){return Math.min(1e3*2**u,3e4)}function Vh(u){return(u??"online")==="online"?qu.isOnline():!0}var oo=class extends Error{constructor(u){super("CancelledError"),this.revert=u?.revert,this.silent=u?.silent}};function Zh(u){let c=!1,o=0,r;const y=Zy(),v=()=>y.status!=="pending",T=L=>{if(!v()){const P=new oo(L);R(P),u.onCancel?.(P)}},E=()=>{c=!0},O=()=>{c=!1},C=()=>Lh.isFocused()&&(u.networkMode==="always"||qu.isOnline())&&u.canRun(),H=()=>Vh(u.networkMode)&&u.canRun(),h=L=>{v()||(r?.(),y.resolve(L))},R=L=>{v()||(r?.(),y.reject(L))},K=()=>new Promise(L=>{r=P=>{(v()||C())&&L(P)},u.onPause?.()}).then(()=>{r=void 0,v()||u.onContinue?.()}),B=()=>{if(v())return;let L;const P=o===0?u.initialPromise:void 0;try{L=P??u.fn()}catch(X){L=Promise.reject(X)}Promise.resolve(L).then(h).catch(X=>{if(v())return;const St=u.retry??(Yu?0:3),st=u.retryDelay??Fy,Tt=typeof st=="function"?st(o,X):st,at=St===!0||typeof St=="number"&&oC()?void 0:K()).then(()=>{c?R(X):B()})})};return{promise:y,status:()=>y.status,cancel:T,continue:()=>(r?.(),y),cancelRetry:E,continueRetry:O,canStart:H,start:()=>(H()?B():K().then(B),y)}}var Kh=class{#t;destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),By(this.gcTime)&&(this.#t=uo.setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(u){this.gcTime=Math.max(this.gcTime||0,u??(Yu?1/0:300*1e3))}clearGcTimeout(){this.#t&&(uo.clearTimeout(this.#t),this.#t=void 0)}},Wy=class extends Kh{#t;#e;#a;#n;#l;#u;#s;constructor(u){super(),this.#s=!1,this.#u=u.defaultOptions,this.setOptions(u.options),this.observers=[],this.#n=u.client,this.#a=this.#n.getQueryCache(),this.queryKey=u.queryKey,this.queryHash=u.queryHash,this.#t=Ah(this.options),this.state=u.state??this.#t,this.scheduleGc()}get meta(){return this.options.meta}get promise(){return this.#l?.promise}setOptions(u){if(this.options={...this.#u,...u},this.updateGcTime(this.options.gcTime),this.state&&this.state.data===void 0){const c=Ah(this.options);c.data!==void 0&&(this.setData(c.data,{updatedAt:c.dataUpdatedAt,manual:!0}),this.#t=c)}}optionalRemove(){!this.observers.length&&this.state.fetchStatus==="idle"&&this.#a.remove(this)}setData(u,c){const o=Gy(this.state.data,u,this.options);return this.#i({data:o,type:"success",dataUpdatedAt:c?.updatedAt,manual:c?.manual}),o}setState(u,c){this.#i({type:"setState",state:u,setStateOptions:c})}cancel(u){const c=this.#l?.promise;return this.#l?.cancel(u),c?c.then($e).catch($e):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}reset(){this.destroy(),this.setState(this.#t)}isActive(){return this.observers.some(u=>jy(u.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===bo||this.state.dataUpdateCount+this.state.errorUpdateCount===0}isStatic(){return this.getObserversCount()>0?this.observers.some(u=>so(u.options.staleTime,this)==="static"):!1}isStale(){return this.getObserversCount()>0?this.observers.some(u=>u.getCurrentResult().isStale):this.state.data===void 0||this.state.isInvalidated}isStaleByTime(u=0){return this.state.data===void 0?!0:u==="static"?!1:this.state.isInvalidated?!0:!qy(this.state.dataUpdatedAt,u)}onFocus(){this.observers.find(c=>c.shouldFetchOnWindowFocus())?.refetch({cancelRefetch:!1}),this.#l?.continue()}onOnline(){this.observers.find(c=>c.shouldFetchOnReconnect())?.refetch({cancelRefetch:!1}),this.#l?.continue()}addObserver(u){this.observers.includes(u)||(this.observers.push(u),this.clearGcTimeout(),this.#a.notify({type:"observerAdded",query:this,observer:u}))}removeObserver(u){this.observers.includes(u)&&(this.observers=this.observers.filter(c=>c!==u),this.observers.length||(this.#l&&(this.#s?this.#l.cancel({revert:!0}):this.#l.cancelRetry()),this.scheduleGc()),this.#a.notify({type:"observerRemoved",query:this,observer:u}))}getObserversCount(){return this.observers.length}invalidate(){this.state.isInvalidated||this.#i({type:"invalidate"})}async fetch(u,c){if(this.state.fetchStatus!=="idle"&&this.#l?.status()!=="rejected"){if(this.state.data!==void 0&&c?.cancelRefetch)this.cancel({silent:!0});else if(this.#l)return this.#l.continueRetry(),this.#l.promise}if(u&&this.setOptions(u),!this.options.queryFn){const E=this.observers.find(O=>O.options.queryFn);E&&this.setOptions(E.options)}const o=new AbortController,r=E=>{Object.defineProperty(E,"signal",{enumerable:!0,get:()=>(this.#s=!0,o.signal)})},y=()=>{const E=Xh(this.options,c),C=(()=>{const H={client:this.#n,queryKey:this.queryKey,meta:this.meta};return r(H),H})();return this.#s=!1,this.options.persister?this.options.persister(E,C,this):E(C)},T=(()=>{const E={fetchOptions:c,options:this.options,queryKey:this.queryKey,client:this.#n,state:this.state,fetchFn:y};return r(E),E})();this.options.behavior?.onFetch(T,this),this.#e=this.state,(this.state.fetchStatus==="idle"||this.state.fetchMeta!==T.fetchOptions?.meta)&&this.#i({type:"fetch",meta:T.fetchOptions?.meta}),this.#l=Zh({initialPromise:c?.initialPromise,fn:T.fetchFn,onCancel:E=>{E instanceof oo&&E.revert&&this.setState({...this.#e,fetchStatus:"idle"}),o.abort()},onFail:(E,O)=>{this.#i({type:"failed",failureCount:E,error:O})},onPause:()=>{this.#i({type:"pause"})},onContinue:()=>{this.#i({type:"continue"})},retry:T.options.retry,retryDelay:T.options.retryDelay,networkMode:T.options.networkMode,canRun:()=>!0});try{const E=await this.#l.start();if(E===void 0)throw new Error(`${this.queryHash} data is undefined`);return this.setData(E),this.#a.config.onSuccess?.(E,this),this.#a.config.onSettled?.(E,this.state.error,this),E}catch(E){if(E instanceof oo){if(E.silent)return this.#l.promise;if(E.revert){if(this.state.data===void 0)throw E;return this.state.data}}throw this.#i({type:"error",error:E}),this.#a.config.onError?.(E,this),this.#a.config.onSettled?.(this.state.data,E,this),E}finally{this.scheduleGc()}}#i(u){const c=o=>{switch(u.type){case"failed":return{...o,fetchFailureCount:u.failureCount,fetchFailureReason:u.error};case"pause":return{...o,fetchStatus:"paused"};case"continue":return{...o,fetchStatus:"fetching"};case"fetch":return{...o,...$y(o.data,this.options),fetchMeta:u.meta??null};case"success":const r={...o,data:u.data,dataUpdateCount:o.dataUpdateCount+1,dataUpdatedAt:u.dataUpdatedAt??Date.now(),error:null,isInvalidated:!1,status:"success",...!u.manual&&{fetchStatus:"idle",fetchFailureCount:0,fetchFailureReason:null}};return this.#e=u.manual?r:void 0,r;case"error":const y=u.error;return{...o,error:y,errorUpdateCount:o.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:o.fetchFailureCount+1,fetchFailureReason:y,fetchStatus:"idle",status:"error"};case"invalidate":return{...o,isInvalidated:!0};case"setState":return{...o,...u.state}}};this.state=c(this.state),de.batch(()=>{this.observers.forEach(o=>{o.onQueryUpdate()}),this.#a.notify({query:this,type:"updated",action:u})})}};function $y(u,c){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:Vh(c.networkMode)?"fetching":"paused",...u===void 0&&{error:null,status:"pending"}}}function Ah(u){const c=typeof u.initialData=="function"?u.initialData():u.initialData,o=c!==void 0,r=o?typeof u.initialDataUpdatedAt=="function"?u.initialDataUpdatedAt():u.initialDataUpdatedAt:0;return{data:c,dataUpdateCount:0,dataUpdatedAt:o?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:o?"success":"pending",fetchStatus:"idle"}}function Mh(u){return{onFetch:(c,o)=>{const r=c.options,y=c.fetchOptions?.meta?.fetchMore?.direction,v=c.state.data?.pages||[],T=c.state.data?.pageParams||[];let E={pages:[],pageParams:[]},O=0;const C=async()=>{let H=!1;const h=B=>{Object.defineProperty(B,"signal",{enumerable:!0,get:()=>(c.signal.aborted?H=!0:c.signal.addEventListener("abort",()=>{H=!0}),c.signal)})},R=Xh(c.options,c.fetchOptions),K=async(B,L,P)=>{if(H)return Promise.reject();if(L==null&&B.pages.length)return Promise.resolve(B);const St=(()=>{const k={client:c.client,queryKey:c.queryKey,pageParam:L,direction:P?"backward":"forward",meta:c.options.meta};return h(k),k})(),st=await R(St),{maxPages:Tt}=c.options,at=P?Ly:Xy;return{pages:at(B.pages,st,Tt),pageParams:at(B.pageParams,L,Tt)}};if(y&&v.length){const B=y==="backward",L=B?Iy:Oh,P={pages:v,pageParams:T},X=L(r,P);E=await K(P,X,B)}else{const B=u??v.length;do{const L=O===0?T[0]??r.initialPageParam:Oh(r,E);if(O>0&&L==null)break;E=await K(E,L),O++}while(Oc.options.persister?.(C,{client:c.client,queryKey:c.queryKey,meta:c.options.meta,signal:c.signal},o):c.fetchFn=C}}}function Oh(u,{pages:c,pageParams:o}){const r=c.length-1;return c.length>0?u.getNextPageParam(c[r],c,o[r],o):void 0}function Iy(u,{pages:c,pageParams:o}){return c.length>0?u.getPreviousPageParam?.(c[0],c,o[0],o):void 0}var Py=class extends Kh{#t;#e;#a;#n;constructor(u){super(),this.#t=u.client,this.mutationId=u.mutationId,this.#a=u.mutationCache,this.#e=[],this.state=u.state||tv(),this.setOptions(u.options),this.scheduleGc()}setOptions(u){this.options=u,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(u){this.#e.includes(u)||(this.#e.push(u),this.clearGcTimeout(),this.#a.notify({type:"observerAdded",mutation:this,observer:u}))}removeObserver(u){this.#e=this.#e.filter(c=>c!==u),this.scheduleGc(),this.#a.notify({type:"observerRemoved",mutation:this,observer:u})}optionalRemove(){this.#e.length||(this.state.status==="pending"?this.scheduleGc():this.#a.remove(this))}continue(){return this.#n?.continue()??this.execute(this.state.variables)}async execute(u){const c=()=>{this.#l({type:"continue"})},o={client:this.#t,meta:this.options.meta,mutationKey:this.options.mutationKey};this.#n=Zh({fn:()=>this.options.mutationFn?this.options.mutationFn(u,o):Promise.reject(new Error("No mutationFn found")),onFail:(v,T)=>{this.#l({type:"failed",failureCount:v,error:T})},onPause:()=>{this.#l({type:"pause"})},onContinue:c,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#a.canRun(this)});const r=this.state.status==="pending",y=!this.#n.canStart();try{if(r)c();else{this.#l({type:"pending",variables:u,isPaused:y}),await this.#a.config.onMutate?.(u,this,o);const T=await this.options.onMutate?.(u,o);T!==this.state.context&&this.#l({type:"pending",context:T,variables:u,isPaused:y})}const v=await this.#n.start();return await this.#a.config.onSuccess?.(v,u,this.state.context,this,o),await this.options.onSuccess?.(v,u,this.state.context,o),await this.#a.config.onSettled?.(v,null,this.state.variables,this.state.context,this,o),await this.options.onSettled?.(v,null,u,this.state.context,o),this.#l({type:"success",data:v}),v}catch(v){try{throw await this.#a.config.onError?.(v,u,this.state.context,this,o),await this.options.onError?.(v,u,this.state.context,o),await this.#a.config.onSettled?.(void 0,v,this.state.variables,this.state.context,this,o),await this.options.onSettled?.(void 0,v,u,this.state.context,o),v}finally{this.#l({type:"error",error:v})}}finally{this.#a.runNext(this)}}#l(u){const c=o=>{switch(u.type){case"failed":return{...o,failureCount:u.failureCount,failureReason:u.error};case"pause":return{...o,isPaused:!0};case"continue":return{...o,isPaused:!1};case"pending":return{...o,context:u.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:u.isPaused,status:"pending",variables:u.variables,submittedAt:Date.now()};case"success":return{...o,data:u.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...o,data:void 0,error:u.error,failureCount:o.failureCount+1,failureReason:u.error,isPaused:!1,status:"error"}}};this.state=c(this.state),de.batch(()=>{this.#e.forEach(o=>{o.onMutationUpdate(u)}),this.#a.notify({mutation:this,type:"updated",action:u})})}};function tv(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}var ev=class extends Qu{constructor(u={}){super(),this.config=u,this.#t=new Set,this.#e=new Map,this.#a=0}#t;#e;#a;build(u,c,o){const r=new Py({client:u,mutationCache:this,mutationId:++this.#a,options:u.defaultMutationOptions(c),state:o});return this.add(r),r}add(u){this.#t.add(u);const c=Uu(u);if(typeof c=="string"){const o=this.#e.get(c);o?o.push(u):this.#e.set(c,[u])}this.notify({type:"added",mutation:u})}remove(u){if(this.#t.delete(u)){const c=Uu(u);if(typeof c=="string"){const o=this.#e.get(c);if(o)if(o.length>1){const r=o.indexOf(u);r!==-1&&o.splice(r,1)}else o[0]===u&&this.#e.delete(c)}}this.notify({type:"removed",mutation:u})}canRun(u){const c=Uu(u);if(typeof c=="string"){const r=this.#e.get(c)?.find(y=>y.state.status==="pending");return!r||r===u}else return!0}runNext(u){const c=Uu(u);return typeof c=="string"?this.#e.get(c)?.find(r=>r!==u&&r.state.isPaused)?.continue()??Promise.resolve():Promise.resolve()}clear(){de.batch(()=>{this.#t.forEach(u=>{this.notify({type:"removed",mutation:u})}),this.#t.clear(),this.#e.clear()})}getAll(){return Array.from(this.#t)}find(u){const c={exact:!0,...u};return this.getAll().find(o=>zh(c,o))}findAll(u={}){return this.getAll().filter(c=>zh(u,c))}notify(u){de.batch(()=>{this.listeners.forEach(c=>{c(u)})})}resumePausedMutations(){const u=this.getAll().filter(c=>c.state.isPaused);return de.batch(()=>Promise.all(u.map(c=>c.continue().catch($e))))}};function Uu(u){return u.options.scope?.id}var av=class extends Qu{constructor(u={}){super(),this.config=u,this.#t=new Map}#t;build(u,c,o){const r=c.queryKey,y=c.queryHash??po(r,c);let v=this.get(y);return v||(v=new Wy({client:u,queryKey:r,queryHash:y,options:u.defaultQueryOptions(c),state:o,defaultOptions:u.getQueryDefaults(r)}),this.add(v)),v}add(u){this.#t.has(u.queryHash)||(this.#t.set(u.queryHash,u),this.notify({type:"added",query:u}))}remove(u){const c=this.#t.get(u.queryHash);c&&(u.destroy(),c===u&&this.#t.delete(u.queryHash),this.notify({type:"removed",query:u}))}clear(){de.batch(()=>{this.getAll().forEach(u=>{this.remove(u)})})}get(u){return this.#t.get(u)}getAll(){return[...this.#t.values()]}find(u){const c={exact:!0,...u};return this.getAll().find(o=>xh(c,o))}findAll(u={}){const c=this.getAll();return Object.keys(u).length>0?c.filter(o=>xh(u,o)):c}notify(u){de.batch(()=>{this.listeners.forEach(c=>{c(u)})})}onFocus(){de.batch(()=>{this.getAll().forEach(u=>{u.onFocus()})})}onOnline(){de.batch(()=>{this.getAll().forEach(u=>{u.onOnline()})})}},lv=class{#t;#e;#a;#n;#l;#u;#s;#i;constructor(u={}){this.#t=u.queryCache||new av,this.#e=u.mutationCache||new ev,this.#a=u.defaultOptions||{},this.#n=new Map,this.#l=new Map,this.#u=0}mount(){this.#u++,this.#u===1&&(this.#s=Lh.subscribe(async u=>{u&&(await this.resumePausedMutations(),this.#t.onFocus())}),this.#i=qu.subscribe(async u=>{u&&(await this.resumePausedMutations(),this.#t.onOnline())}))}unmount(){this.#u--,this.#u===0&&(this.#s?.(),this.#s=void 0,this.#i?.(),this.#i=void 0)}isFetching(u){return this.#t.findAll({...u,fetchStatus:"fetching"}).length}isMutating(u){return this.#e.findAll({...u,status:"pending"}).length}getQueryData(u){const c=this.defaultQueryOptions({queryKey:u});return this.#t.get(c.queryHash)?.state.data}ensureQueryData(u){const c=this.defaultQueryOptions(u),o=this.#t.build(this,c),r=o.state.data;return r===void 0?this.fetchQuery(u):(u.revalidateIfStale&&o.isStaleByTime(so(c.staleTime,o))&&this.prefetchQuery(c),Promise.resolve(r))}getQueriesData(u){return this.#t.findAll(u).map(({queryKey:c,state:o})=>{const r=o.data;return[c,r]})}setQueryData(u,c,o){const r=this.defaultQueryOptions({queryKey:u}),v=this.#t.get(r.queryHash)?.state.data,T=Hy(c,v);if(T!==void 0)return this.#t.build(this,r).setData(T,{...o,manual:!0})}setQueriesData(u,c,o){return de.batch(()=>this.#t.findAll(u).map(({queryKey:r})=>[r,this.setQueryData(r,c,o)]))}getQueryState(u){const c=this.defaultQueryOptions({queryKey:u});return this.#t.get(c.queryHash)?.state}removeQueries(u){const c=this.#t;de.batch(()=>{c.findAll(u).forEach(o=>{c.remove(o)})})}resetQueries(u,c){const o=this.#t;return de.batch(()=>(o.findAll(u).forEach(r=>{r.reset()}),this.refetchQueries({type:"active",...u},c)))}cancelQueries(u,c={}){const o={revert:!0,...c},r=de.batch(()=>this.#t.findAll(u).map(y=>y.cancel(o)));return Promise.all(r).then($e).catch($e)}invalidateQueries(u,c={}){return de.batch(()=>(this.#t.findAll(u).forEach(o=>{o.invalidate()}),u?.refetchType==="none"?Promise.resolve():this.refetchQueries({...u,type:u?.refetchType??u?.type??"active"},c)))}refetchQueries(u,c={}){const o={...c,cancelRefetch:c.cancelRefetch??!0},r=de.batch(()=>this.#t.findAll(u).filter(y=>!y.isDisabled()&&!y.isStatic()).map(y=>{let v=y.fetch(void 0,o);return o.throwOnError||(v=v.catch($e)),y.state.fetchStatus==="paused"?Promise.resolve():v}));return Promise.all(r).then($e)}fetchQuery(u){const c=this.defaultQueryOptions(u);c.retry===void 0&&(c.retry=!1);const o=this.#t.build(this,c);return o.isStaleByTime(so(c.staleTime,o))?o.fetch(c):Promise.resolve(o.state.data)}prefetchQuery(u){return this.fetchQuery(u).then($e).catch($e)}fetchInfiniteQuery(u){return u.behavior=Mh(u.pages),this.fetchQuery(u)}prefetchInfiniteQuery(u){return this.fetchInfiniteQuery(u).then($e).catch($e)}ensureInfiniteQueryData(u){return u.behavior=Mh(u.pages),this.ensureQueryData(u)}resumePausedMutations(){return qu.isOnline()?this.#e.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#t}getMutationCache(){return this.#e}getDefaultOptions(){return this.#a}setDefaultOptions(u){this.#a=u}setQueryDefaults(u,c){this.#n.set(yi(u),{queryKey:u,defaultOptions:c})}getQueryDefaults(u){const c=[...this.#n.values()],o={};return c.forEach(r=>{vi(u,r.queryKey)&&Object.assign(o,r.defaultOptions)}),o}setMutationDefaults(u,c){this.#l.set(yi(u),{mutationKey:u,defaultOptions:c})}getMutationDefaults(u){const c=[...this.#l.values()],o={};return c.forEach(r=>{vi(u,r.mutationKey)&&Object.assign(o,r.defaultOptions)}),o}defaultQueryOptions(u){if(u._defaulted)return u;const c={...this.#a.queries,...this.getQueryDefaults(u.queryKey),...u,_defaulted:!0};return c.queryHash||(c.queryHash=po(c.queryKey,c)),c.refetchOnReconnect===void 0&&(c.refetchOnReconnect=c.networkMode!=="always"),c.throwOnError===void 0&&(c.throwOnError=!!c.suspense),!c.networkMode&&c.persister&&(c.networkMode="offlineFirst"),c.queryFn===bo&&(c.enabled=!1),c}defaultMutationOptions(u){return u?._defaulted?u:{...this.#a.mutations,...u?.mutationKey&&this.getMutationDefaults(u.mutationKey),...u,_defaulted:!0}}clear(){this.#t.clear(),this.#e.clear()}},nv=W.createContext(void 0),iv=({client:u,children:c})=>(W.useEffect(()=>(u.mount(),()=>{u.unmount()}),[u]),I.jsx(nv.Provider,{value:u,children:c})),uv=(u,c,o,r,y,v,T,E)=>{let O=document.documentElement,C=["light","dark"];function H(K){(Array.isArray(u)?u:[u]).forEach(B=>{let L=B==="class",P=L&&v?y.map(X=>v[X]||X):y;L?(O.classList.remove(...P),O.classList.add(v&&v[K]?v[K]:K)):O.setAttribute(B,K)}),h(K)}function h(K){E&&C.includes(K)&&(O.style.colorScheme=K)}function R(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}if(r)H(r);else try{let K=localStorage.getItem(c)||o,B=T&&K==="system"?R():K;H(B)}catch{}},wh=["light","dark"],Jh="(prefers-color-scheme: dark)",sv=typeof window>"u",So=W.createContext(void 0),cv={setTheme:u=>{},themes:[]},ov=()=>{var u;return(u=W.useContext(So))!=null?u:cv},rv=u=>W.useContext(So)?W.createElement(W.Fragment,null,u.children):W.createElement(dv,{...u}),fv=["light","dark"],dv=({forcedTheme:u,disableTransitionOnChange:c=!1,enableSystem:o=!0,enableColorScheme:r=!0,storageKey:y="theme",themes:v=fv,defaultTheme:T=o?"system":"light",attribute:E="data-theme",value:O,children:C,nonce:H,scriptProps:h})=>{let[R,K]=W.useState(()=>mv(y,T)),[B,L]=W.useState(()=>R==="system"?lo():R),P=O?Object.values(O):v,X=W.useCallback(at=>{let k=at;if(!k)return;at==="system"&&o&&(k=lo());let At=O?O[k]:k,q=c?yv(H):null,Ot=document.documentElement,ue=Gt=>{Gt==="class"?(Ot.classList.remove(...P),At&&Ot.classList.add(At)):Gt.startsWith("data-")&&(At?Ot.setAttribute(Gt,At):Ot.removeAttribute(Gt))};if(Array.isArray(E)?E.forEach(ue):ue(E),r){let Gt=wh.includes(T)?T:null,Dt=wh.includes(k)?k:Gt;Ot.style.colorScheme=Dt}q?.()},[H]),St=W.useCallback(at=>{let k=typeof at=="function"?at(R):at;K(k);try{localStorage.setItem(y,k)}catch{}},[R]),st=W.useCallback(at=>{let k=lo(at);L(k),R==="system"&&o&&!u&&X("system")},[R,u]);W.useEffect(()=>{let at=window.matchMedia(Jh);return at.addListener(st),st(at),()=>at.removeListener(st)},[st]),W.useEffect(()=>{let at=k=>{k.key===y&&(k.newValue?K(k.newValue):St(T))};return window.addEventListener("storage",at),()=>window.removeEventListener("storage",at)},[St]),W.useEffect(()=>{X(u??R)},[u,R]);let Tt=W.useMemo(()=>({theme:R,setTheme:St,forcedTheme:u,resolvedTheme:R==="system"?B:R,themes:o?[...v,"system"]:v,systemTheme:o?B:void 0}),[R,St,u,B,o,v]);return W.createElement(So.Provider,{value:Tt},W.createElement(hv,{forcedTheme:u,storageKey:y,attribute:E,enableSystem:o,enableColorScheme:r,defaultTheme:T,value:O,themes:v,nonce:H,scriptProps:h}),C)},hv=W.memo(({forcedTheme:u,storageKey:c,attribute:o,enableSystem:r,enableColorScheme:y,defaultTheme:v,value:T,themes:E,nonce:O,scriptProps:C})=>{let H=JSON.stringify([o,c,v,u,E,T,r,y]).slice(1,-1);return W.createElement("script",{...C,suppressHydrationWarning:!0,nonce:typeof window>"u"?O:"",dangerouslySetInnerHTML:{__html:`(${uv.toString()})(${H})`}})}),mv=(u,c)=>{if(sv)return;let o;try{o=localStorage.getItem(u)||void 0}catch{}return o||c},yv=u=>{let c=document.createElement("style");return u&&c.setAttribute("nonce",u),c.appendChild(document.createTextNode("*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),document.head.appendChild(c),()=>{window.getComputedStyle(document.body),setTimeout(()=>{document.head.removeChild(c)},1)}},lo=u=>(u||(u=window.matchMedia(Jh)),u.matches?"dark":"light");function vv({children:u,defaultTheme:c="system",storageKey:o="vite-ui-theme"}){return I.jsx(rv,{attribute:"class",defaultTheme:c,enableSystem:!0,storageKey:o,disableTransitionOnChange:!0,children:u})}const gv=u=>u.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),pv=u=>u.replace(/^([A-Z])|[\s-_]+(\w)/g,(c,o,r)=>r?r.toUpperCase():o.toLowerCase()),Dh=u=>{const c=pv(u);return c.charAt(0).toUpperCase()+c.slice(1)},kh=(...u)=>u.filter((c,o,r)=>!!c&&c.trim()!==""&&r.indexOf(c)===o).join(" ").trim(),bv=u=>{for(const c in u)if(c.startsWith("aria-")||c==="role"||c==="title")return!0};var Sv={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};const xv=W.forwardRef(({color:u="currentColor",size:c=24,strokeWidth:o=2,absoluteStrokeWidth:r,className:y="",children:v,iconNode:T,...E},O)=>W.createElement("svg",{ref:O,...Sv,width:c,height:c,stroke:u,strokeWidth:r?Number(o)*24/Number(c):o,className:kh("lucide",y),...!v&&!bv(E)&&{"aria-hidden":"true"},...E},[...T.map(([C,H])=>W.createElement(C,H)),...Array.isArray(v)?v:[v]]));const gi=(u,c)=>{const o=W.forwardRef(({className:r,...y},v)=>W.createElement(xv,{ref:v,iconNode:c,className:kh(`lucide-${gv(Dh(u))}`,`lucide-${u}`,r),...y}));return o.displayName=Dh(u),o};const zv=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],Ev=gi("circle-check",zv);const Tv=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],Av=gi("info",Tv);const Mv=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],Ov=gi("loader-circle",Mv);const wv=[["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z",key:"2d38gg"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]],Dv=gi("octagon-x",wv);const Cv=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],Nv=gi("triangle-alert",Cv);function _v(u){if(typeof document>"u")return;let c=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css",c.appendChild(o),o.styleSheet?o.styleSheet.cssText=u:o.appendChild(document.createTextNode(u))}const Uv=u=>{switch(u){case"success":return Bv;case"info":return jv;case"warning":return qv;case"error":return Qv;default:return null}},Rv=Array(12).fill(0),Hv=({visible:u,className:c})=>_.createElement("div",{className:["sonner-loading-wrapper",c].filter(Boolean).join(" "),"data-visible":u},_.createElement("div",{className:"sonner-spinner"},Rv.map((o,r)=>_.createElement("div",{className:"sonner-loading-bar",key:`spinner-bar-${r}`})))),Bv=_.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},_.createElement("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z",clipRule:"evenodd"})),qv=_.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",height:"20",width:"20"},_.createElement("path",{fillRule:"evenodd",d:"M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z",clipRule:"evenodd"})),jv=_.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},_.createElement("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z",clipRule:"evenodd"})),Qv=_.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},_.createElement("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z",clipRule:"evenodd"})),Yv=_.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"},_.createElement("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),_.createElement("line",{x1:"6",y1:"6",x2:"18",y2:"18"})),Gv=()=>{const[u,c]=_.useState(document.hidden);return _.useEffect(()=>{const o=()=>{c(document.hidden)};return document.addEventListener("visibilitychange",o),()=>window.removeEventListener("visibilitychange",o)},[]),u};let ro=1;class Xv{constructor(){this.subscribe=c=>(this.subscribers.push(c),()=>{const o=this.subscribers.indexOf(c);this.subscribers.splice(o,1)}),this.publish=c=>{this.subscribers.forEach(o=>o(c))},this.addToast=c=>{this.publish(c),this.toasts=[...this.toasts,c]},this.create=c=>{var o;const{message:r,...y}=c,v=typeof c?.id=="number"||((o=c.id)==null?void 0:o.length)>0?c.id:ro++,T=this.toasts.find(O=>O.id===v),E=c.dismissible===void 0?!0:c.dismissible;return this.dismissedToasts.has(v)&&this.dismissedToasts.delete(v),T?this.toasts=this.toasts.map(O=>O.id===v?(this.publish({...O,...c,id:v,title:r}),{...O,...c,id:v,dismissible:E,title:r}):O):this.addToast({title:r,...y,dismissible:E,id:v}),v},this.dismiss=c=>(c?(this.dismissedToasts.add(c),requestAnimationFrame(()=>this.subscribers.forEach(o=>o({id:c,dismiss:!0})))):this.toasts.forEach(o=>{this.subscribers.forEach(r=>r({id:o.id,dismiss:!0}))}),c),this.message=(c,o)=>this.create({...o,message:c}),this.error=(c,o)=>this.create({...o,message:c,type:"error"}),this.success=(c,o)=>this.create({...o,type:"success",message:c}),this.info=(c,o)=>this.create({...o,type:"info",message:c}),this.warning=(c,o)=>this.create({...o,type:"warning",message:c}),this.loading=(c,o)=>this.create({...o,type:"loading",message:c}),this.promise=(c,o)=>{if(!o)return;let r;o.loading!==void 0&&(r=this.create({...o,promise:c,type:"loading",message:o.loading,description:typeof o.description!="function"?o.description:void 0}));const y=Promise.resolve(c instanceof Function?c():c);let v=r!==void 0,T;const E=y.then(async C=>{if(T=["resolve",C],_.isValidElement(C))v=!1,this.create({id:r,type:"default",message:C});else if(Vv(C)&&!C.ok){v=!1;const h=typeof o.error=="function"?await o.error(`HTTP error! status: ${C.status}`):o.error,R=typeof o.description=="function"?await o.description(`HTTP error! status: ${C.status}`):o.description,B=typeof h=="object"&&!_.isValidElement(h)?h:{message:h};this.create({id:r,type:"error",description:R,...B})}else if(C instanceof Error){v=!1;const h=typeof o.error=="function"?await o.error(C):o.error,R=typeof o.description=="function"?await o.description(C):o.description,B=typeof h=="object"&&!_.isValidElement(h)?h:{message:h};this.create({id:r,type:"error",description:R,...B})}else if(o.success!==void 0){v=!1;const h=typeof o.success=="function"?await o.success(C):o.success,R=typeof o.description=="function"?await o.description(C):o.description,B=typeof h=="object"&&!_.isValidElement(h)?h:{message:h};this.create({id:r,type:"success",description:R,...B})}}).catch(async C=>{if(T=["reject",C],o.error!==void 0){v=!1;const H=typeof o.error=="function"?await o.error(C):o.error,h=typeof o.description=="function"?await o.description(C):o.description,K=typeof H=="object"&&!_.isValidElement(H)?H:{message:H};this.create({id:r,type:"error",description:h,...K})}}).finally(()=>{v&&(this.dismiss(r),r=void 0),o.finally==null||o.finally.call(o)}),O=()=>new Promise((C,H)=>E.then(()=>T[0]==="reject"?H(T[1]):C(T[1])).catch(H));return typeof r!="string"&&typeof r!="number"?{unwrap:O}:Object.assign(r,{unwrap:O})},this.custom=(c,o)=>{const r=o?.id||ro++;return this.create({jsx:c(r),id:r,...o}),r},this.getActiveToasts=()=>this.toasts.filter(c=>!this.dismissedToasts.has(c.id)),this.subscribers=[],this.toasts=[],this.dismissedToasts=new Set}}const Te=new Xv,Lv=(u,c)=>{const o=c?.id||ro++;return Te.addToast({title:u,...c,id:o}),o},Vv=u=>u&&typeof u=="object"&&"ok"in u&&typeof u.ok=="boolean"&&"status"in u&&typeof u.status=="number",Zv=Lv,Kv=()=>Te.toasts,Jv=()=>Te.getActiveToasts();Object.assign(Zv,{success:Te.success,info:Te.info,warning:Te.warning,error:Te.error,custom:Te.custom,message:Te.message,promise:Te.promise,dismiss:Te.dismiss,loading:Te.loading},{getHistory:Kv,getToasts:Jv});_v("[data-sonner-toaster][dir=ltr],html[dir=ltr]{--toast-icon-margin-start:-3px;--toast-icon-margin-end:4px;--toast-svg-margin-start:-1px;--toast-svg-margin-end:0px;--toast-button-margin-start:auto;--toast-button-margin-end:0;--toast-close-button-start:0;--toast-close-button-end:unset;--toast-close-button-transform:translate(-35%, -35%)}[data-sonner-toaster][dir=rtl],html[dir=rtl]{--toast-icon-margin-start:4px;--toast-icon-margin-end:-3px;--toast-svg-margin-start:0px;--toast-svg-margin-end:-1px;--toast-button-margin-start:0;--toast-button-margin-end:auto;--toast-close-button-start:unset;--toast-close-button-end:0;--toast-close-button-transform:translate(35%, -35%)}[data-sonner-toaster]{position:fixed;width:var(--width);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;--gray1:hsl(0, 0%, 99%);--gray2:hsl(0, 0%, 97.3%);--gray3:hsl(0, 0%, 95.1%);--gray4:hsl(0, 0%, 93%);--gray5:hsl(0, 0%, 90.9%);--gray6:hsl(0, 0%, 88.7%);--gray7:hsl(0, 0%, 85.8%);--gray8:hsl(0, 0%, 78%);--gray9:hsl(0, 0%, 56.1%);--gray10:hsl(0, 0%, 52.3%);--gray11:hsl(0, 0%, 43.5%);--gray12:hsl(0, 0%, 9%);--border-radius:8px;box-sizing:border-box;padding:0;margin:0;list-style:none;outline:0;z-index:999999999;transition:transform .4s ease}@media (hover:none) and (pointer:coarse){[data-sonner-toaster][data-lifted=true]{transform:none}}[data-sonner-toaster][data-x-position=right]{right:var(--offset-right)}[data-sonner-toaster][data-x-position=left]{left:var(--offset-left)}[data-sonner-toaster][data-x-position=center]{left:50%;transform:translateX(-50%)}[data-sonner-toaster][data-y-position=top]{top:var(--offset-top)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--offset-bottom)}[data-sonner-toast]{--y:translateY(100%);--lift-amount:calc(var(--lift) * var(--gap));z-index:var(--z-index);position:absolute;opacity:0;transform:var(--y);touch-action:none;transition:transform .4s,opacity .4s,height .4s,box-shadow .2s;box-sizing:border-box;outline:0;overflow-wrap:anywhere}[data-sonner-toast][data-styled=true]{padding:16px;background:var(--normal-bg);border:1px solid var(--normal-border);color:var(--normal-text);border-radius:var(--border-radius);box-shadow:0 4px 12px rgba(0,0,0,.1);width:var(--width);font-size:13px;display:flex;align-items:center;gap:6px}[data-sonner-toast]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-y-position=top]{top:0;--y:translateY(-100%);--lift:1;--lift-amount:calc(1 * var(--gap))}[data-sonner-toast][data-y-position=bottom]{bottom:0;--y:translateY(100%);--lift:-1;--lift-amount:calc(var(--lift) * var(--gap))}[data-sonner-toast][data-styled=true] [data-description]{font-weight:400;line-height:1.4;color:#3f3f3f}[data-rich-colors=true][data-sonner-toast][data-styled=true] [data-description]{color:inherit}[data-sonner-toaster][data-sonner-theme=dark] [data-description]{color:#e8e8e8}[data-sonner-toast][data-styled=true] [data-title]{font-weight:500;line-height:1.5;color:inherit}[data-sonner-toast][data-styled=true] [data-icon]{display:flex;height:16px;width:16px;position:relative;justify-content:flex-start;align-items:center;flex-shrink:0;margin-left:var(--toast-icon-margin-start);margin-right:var(--toast-icon-margin-end)}[data-sonner-toast][data-promise=true] [data-icon]>svg{opacity:0;transform:scale(.8);transform-origin:center;animation:sonner-fade-in .3s ease forwards}[data-sonner-toast][data-styled=true] [data-icon]>*{flex-shrink:0}[data-sonner-toast][data-styled=true] [data-icon] svg{margin-left:var(--toast-svg-margin-start);margin-right:var(--toast-svg-margin-end)}[data-sonner-toast][data-styled=true] [data-content]{display:flex;flex-direction:column;gap:2px}[data-sonner-toast][data-styled=true] [data-button]{border-radius:4px;padding-left:8px;padding-right:8px;height:24px;font-size:12px;color:var(--normal-bg);background:var(--normal-text);margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end);border:none;font-weight:500;cursor:pointer;outline:0;display:flex;align-items:center;flex-shrink:0;transition:opacity .4s,box-shadow .2s}[data-sonner-toast][data-styled=true] [data-button]:focus-visible{box-shadow:0 0 0 2px rgba(0,0,0,.4)}[data-sonner-toast][data-styled=true] [data-button]:first-of-type{margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end)}[data-sonner-toast][data-styled=true] [data-cancel]{color:var(--normal-text);background:rgba(0,0,0,.08)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-styled=true] [data-cancel]{background:rgba(255,255,255,.3)}[data-sonner-toast][data-styled=true] [data-close-button]{position:absolute;left:var(--toast-close-button-start);right:var(--toast-close-button-end);top:0;height:20px;width:20px;display:flex;justify-content:center;align-items:center;padding:0;color:var(--gray12);background:var(--normal-bg);border:1px solid var(--gray4);transform:var(--toast-close-button-transform);border-radius:50%;cursor:pointer;z-index:1;transition:opacity .1s,background .2s,border-color .2s}[data-sonner-toast][data-styled=true] [data-close-button]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-styled=true] [data-disabled=true]{cursor:not-allowed}[data-sonner-toast][data-styled=true]:hover [data-close-button]:hover{background:var(--gray2);border-color:var(--gray5)}[data-sonner-toast][data-swiping=true]::before{content:'';position:absolute;left:-100%;right:-100%;height:100%;z-index:-1}[data-sonner-toast][data-y-position=top][data-swiping=true]::before{bottom:50%;transform:scaleY(3) translateY(50%)}[data-sonner-toast][data-y-position=bottom][data-swiping=true]::before{top:50%;transform:scaleY(3) translateY(-50%)}[data-sonner-toast][data-swiping=false][data-removed=true]::before{content:'';position:absolute;inset:0;transform:scaleY(2)}[data-sonner-toast][data-expanded=true]::after{content:'';position:absolute;left:0;height:calc(var(--gap) + 1px);bottom:100%;width:100%}[data-sonner-toast][data-mounted=true]{--y:translateY(0);opacity:1}[data-sonner-toast][data-expanded=false][data-front=false]{--scale:var(--toasts-before) * 0.05 + 1;--y:translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)));height:var(--front-toast-height)}[data-sonner-toast]>*{transition:opacity .4s}[data-sonner-toast][data-x-position=right]{right:0}[data-sonner-toast][data-x-position=left]{left:0}[data-sonner-toast][data-expanded=false][data-front=false][data-styled=true]>*{opacity:0}[data-sonner-toast][data-visible=false]{opacity:0;pointer-events:none}[data-sonner-toast][data-mounted=true][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset)));height:var(--initial-height)}[data-sonner-toast][data-removed=true][data-front=true][data-swipe-out=false]{--y:translateY(calc(var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=false]{--y:translateY(40%);opacity:0;transition:transform .5s,opacity .2s}[data-sonner-toast][data-removed=true][data-front=false]::before{height:calc(var(--initial-height) + 20%)}[data-sonner-toast][data-swiping=true]{transform:var(--y) translateY(var(--swipe-amount-y,0)) translateX(var(--swipe-amount-x,0));transition:none}[data-sonner-toast][data-swiped=true]{user-select:none}[data-sonner-toast][data-swipe-out=true][data-y-position=bottom],[data-sonner-toast][data-swipe-out=true][data-y-position=top]{animation-duration:.2s;animation-timing-function:ease-out;animation-fill-mode:forwards}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=left]{animation-name:swipe-out-left}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=right]{animation-name:swipe-out-right}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=up]{animation-name:swipe-out-up}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=down]{animation-name:swipe-out-down}@keyframes swipe-out-left{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) - 100%));opacity:0}}@keyframes swipe-out-right{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) + 100%));opacity:0}}@keyframes swipe-out-up{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) - 100%));opacity:0}}@keyframes swipe-out-down{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) + 100%));opacity:0}}@media (max-width:600px){[data-sonner-toaster]{position:fixed;right:var(--mobile-offset-right);left:var(--mobile-offset-left);width:100%}[data-sonner-toaster][dir=rtl]{left:calc(var(--mobile-offset-left) * -1)}[data-sonner-toaster] [data-sonner-toast]{left:0;right:0;width:calc(100% - var(--mobile-offset-left) * 2)}[data-sonner-toaster][data-x-position=left]{left:var(--mobile-offset-left)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--mobile-offset-bottom)}[data-sonner-toaster][data-y-position=top]{top:var(--mobile-offset-top)}[data-sonner-toaster][data-x-position=center]{left:var(--mobile-offset-left);right:var(--mobile-offset-right);transform:none}}[data-sonner-toaster][data-sonner-theme=light]{--normal-bg:#fff;--normal-border:var(--gray4);--normal-text:var(--gray12);--success-bg:hsl(143, 85%, 96%);--success-border:hsl(145, 92%, 87%);--success-text:hsl(140, 100%, 27%);--info-bg:hsl(208, 100%, 97%);--info-border:hsl(221, 91%, 93%);--info-text:hsl(210, 92%, 45%);--warning-bg:hsl(49, 100%, 97%);--warning-border:hsl(49, 91%, 84%);--warning-text:hsl(31, 92%, 45%);--error-bg:hsl(359, 100%, 97%);--error-border:hsl(359, 100%, 94%);--error-text:hsl(360, 100%, 45%)}[data-sonner-toaster][data-sonner-theme=light] [data-sonner-toast][data-invert=true]{--normal-bg:#000;--normal-border:hsl(0, 0%, 20%);--normal-text:var(--gray1)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-invert=true]{--normal-bg:#fff;--normal-border:var(--gray3);--normal-text:var(--gray12)}[data-sonner-toaster][data-sonner-theme=dark]{--normal-bg:#000;--normal-bg-hover:hsl(0, 0%, 12%);--normal-border:hsl(0, 0%, 20%);--normal-border-hover:hsl(0, 0%, 25%);--normal-text:var(--gray1);--success-bg:hsl(150, 100%, 6%);--success-border:hsl(147, 100%, 12%);--success-text:hsl(150, 86%, 65%);--info-bg:hsl(215, 100%, 6%);--info-border:hsl(223, 43%, 17%);--info-text:hsl(216, 87%, 65%);--warning-bg:hsl(64, 100%, 6%);--warning-border:hsl(60, 100%, 9%);--warning-text:hsl(46, 87%, 65%);--error-bg:hsl(358, 76%, 10%);--error-border:hsl(357, 89%, 16%);--error-text:hsl(358, 100%, 81%)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]{background:var(--normal-bg);border-color:var(--normal-border);color:var(--normal-text)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]:hover{background:var(--normal-bg-hover);border-color:var(--normal-border-hover)}[data-rich-colors=true][data-sonner-toast][data-type=success]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=success] [data-close-button]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=info]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=info] [data-close-button]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning] [data-close-button]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=error]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}[data-rich-colors=true][data-sonner-toast][data-type=error] [data-close-button]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}.sonner-loading-wrapper{--size:16px;height:var(--size);width:var(--size);position:absolute;inset:0;z-index:10}.sonner-loading-wrapper[data-visible=false]{transform-origin:center;animation:sonner-fade-out .2s ease forwards}.sonner-spinner{position:relative;top:50%;left:50%;height:var(--size);width:var(--size)}.sonner-loading-bar{animation:sonner-spin 1.2s linear infinite;background:var(--gray11);border-radius:6px;height:8%;left:-10%;position:absolute;top:-3.9%;width:24%}.sonner-loading-bar:first-child{animation-delay:-1.2s;transform:rotate(.0001deg) translate(146%)}.sonner-loading-bar:nth-child(2){animation-delay:-1.1s;transform:rotate(30deg) translate(146%)}.sonner-loading-bar:nth-child(3){animation-delay:-1s;transform:rotate(60deg) translate(146%)}.sonner-loading-bar:nth-child(4){animation-delay:-.9s;transform:rotate(90deg) translate(146%)}.sonner-loading-bar:nth-child(5){animation-delay:-.8s;transform:rotate(120deg) translate(146%)}.sonner-loading-bar:nth-child(6){animation-delay:-.7s;transform:rotate(150deg) translate(146%)}.sonner-loading-bar:nth-child(7){animation-delay:-.6s;transform:rotate(180deg) translate(146%)}.sonner-loading-bar:nth-child(8){animation-delay:-.5s;transform:rotate(210deg) translate(146%)}.sonner-loading-bar:nth-child(9){animation-delay:-.4s;transform:rotate(240deg) translate(146%)}.sonner-loading-bar:nth-child(10){animation-delay:-.3s;transform:rotate(270deg) translate(146%)}.sonner-loading-bar:nth-child(11){animation-delay:-.2s;transform:rotate(300deg) translate(146%)}.sonner-loading-bar:nth-child(12){animation-delay:-.1s;transform:rotate(330deg) translate(146%)}@keyframes sonner-fade-in{0%{opacity:0;transform:scale(.8)}100%{opacity:1;transform:scale(1)}}@keyframes sonner-fade-out{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.8)}}@keyframes sonner-spin{0%{opacity:1}100%{opacity:.15}}@media (prefers-reduced-motion){.sonner-loading-bar,[data-sonner-toast],[data-sonner-toast]>*{transition:none!important;animation:none!important}}.sonner-loader{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;transition:opacity .2s,transform .2s}.sonner-loader[data-visible=false]{opacity:0;transform:scale(.8) translate(-50%,-50%)}");function Ru(u){return u.label!==void 0}const kv=3,Fv="24px",Wv="16px",Ch=4e3,$v=356,Iv=14,Pv=45,tg=200;function na(...u){return u.filter(Boolean).join(" ")}function eg(u){const[c,o]=u.split("-"),r=[];return c&&r.push(c),o&&r.push(o),r}const ag=u=>{var c,o,r,y,v,T,E,O,C;const{invert:H,toast:h,unstyled:R,interacting:K,setHeights:B,visibleToasts:L,heights:P,index:X,toasts:St,expanded:st,removeToast:Tt,defaultRichColors:at,closeButton:k,style:At,cancelButtonStyle:q,actionButtonStyle:Ot,className:ue="",descriptionClassName:Gt="",duration:Dt,position:kt,gap:he,expandByDefault:Bt,classNames:S,icons:N,closeButtonAriaLabel:D="Close toast"}=u,[ct,et]=_.useState(null),[wt,dt]=_.useState(null),[U,Z]=_.useState(!1),[nt,_t]=_.useState(!1),[gt,ht]=_.useState(!1),[Ft,Ae]=_.useState(!1),[Me,se]=_.useState(!1),[pi,Ze]=_.useState(0),[gn,Al]=_.useState(0),tl=_.useRef(h.duration||Dt||Ch),pn=_.useRef(null),Oe=_.useRef(null),bn=X===0,Sn=X+1<=L,ce=h.type,Ma=h.dismissible!==!1,oe=h.className||"",Gu=h.descriptionClassName||"",el=_.useMemo(()=>P.findIndex(F=>F.toastId===h.id)||0,[P,h.id]),bi=_.useMemo(()=>{var F;return(F=h.closeButton)!=null?F:k},[h.closeButton,k]),al=_.useMemo(()=>h.duration||Dt||Ch,[h.duration,Dt]),xn=_.useRef(0),ua=_.useRef(0),Si=_.useRef(0),Oa=_.useRef(null),[ll,re]=kt.split("-"),Ke=_.useMemo(()=>P.reduce((F,Ut,Wt)=>Wt>=el?F:F+Ut.height,0),[P,el]),ne=Gv(),Xu=h.invert||H,zn=ce==="loading";ua.current=_.useMemo(()=>el*he+Ke,[el,Ke]),_.useEffect(()=>{tl.current=al},[al]),_.useEffect(()=>{Z(!0)},[]),_.useEffect(()=>{const F=Oe.current;if(F){const Ut=F.getBoundingClientRect().height;return Al(Ut),B(Wt=>[{toastId:h.id,height:Ut,position:h.position},...Wt]),()=>B(Wt=>Wt.filter(ie=>ie.toastId!==h.id))}},[B,h.id]),_.useLayoutEffect(()=>{if(!U)return;const F=Oe.current,Ut=F.style.height;F.style.height="auto";const Wt=F.getBoundingClientRect().height;F.style.height=Ut,Al(Wt),B(ie=>ie.find(Ht=>Ht.toastId===h.id)?ie.map(Ht=>Ht.toastId===h.id?{...Ht,height:Wt}:Ht):[{toastId:h.id,height:Wt,position:h.position},...ie])},[U,h.title,h.description,B,h.id,h.jsx,h.action,h.cancel]);const Ie=_.useCallback(()=>{_t(!0),Ze(ua.current),B(F=>F.filter(Ut=>Ut.toastId!==h.id)),setTimeout(()=>{Tt(h)},tg)},[h,Tt,B,ua]);_.useEffect(()=>{if(h.promise&&ce==="loading"||h.duration===1/0||h.type==="loading")return;let F;return st||K||ne?(()=>{if(Si.current{tl.current!==1/0&&(xn.current=new Date().getTime(),F=setTimeout(()=>{h.onAutoClose==null||h.onAutoClose.call(h,h),Ie()},tl.current))})(),()=>clearTimeout(F)},[st,K,h,ce,ne,Ie]),_.useEffect(()=>{h.delete&&(Ie(),h.onDismiss==null||h.onDismiss.call(h,h))},[Ie,h.delete]);function Ml(){var F;if(N?.loading){var Ut;return _.createElement("div",{className:na(S?.loader,h==null||(Ut=h.classNames)==null?void 0:Ut.loader,"sonner-loader"),"data-visible":ce==="loading"},N.loading)}return _.createElement(Hv,{className:na(S?.loader,h==null||(F=h.classNames)==null?void 0:F.loader),visible:ce==="loading"})}const Ol=h.icon||N?.[ce]||Uv(ce);var nl,Pe;return _.createElement("li",{tabIndex:0,ref:Oe,className:na(ue,oe,S?.toast,h==null||(c=h.classNames)==null?void 0:c.toast,S?.default,S?.[ce],h==null||(o=h.classNames)==null?void 0:o[ce]),"data-sonner-toast":"","data-rich-colors":(nl=h.richColors)!=null?nl:at,"data-styled":!(h.jsx||h.unstyled||R),"data-mounted":U,"data-promise":!!h.promise,"data-swiped":Me,"data-removed":nt,"data-visible":Sn,"data-y-position":ll,"data-x-position":re,"data-index":X,"data-front":bn,"data-swiping":gt,"data-dismissible":Ma,"data-type":ce,"data-invert":Xu,"data-swipe-out":Ft,"data-swipe-direction":wt,"data-expanded":!!(st||Bt&&U),"data-testid":h.testId,style:{"--index":X,"--toasts-before":X,"--z-index":St.length-X,"--offset":`${nt?pi:ua.current}px`,"--initial-height":Bt?"auto":`${gn}px`,...At,...h.style},onDragEnd:()=>{ht(!1),et(null),Oa.current=null},onPointerDown:F=>{F.button!==2&&(zn||!Ma||(pn.current=new Date,Ze(ua.current),F.target.setPointerCapture(F.pointerId),F.target.tagName!=="BUTTON"&&(ht(!0),Oa.current={x:F.clientX,y:F.clientY})))},onPointerUp:()=>{var F,Ut,Wt;if(Ft||!Ma)return;Oa.current=null;const ie=Number(((F=Oe.current)==null?void 0:F.style.getPropertyValue("--swipe-amount-x").replace("px",""))||0),wa=Number(((Ut=Oe.current)==null?void 0:Ut.style.getPropertyValue("--swipe-amount-y").replace("px",""))||0),Ht=new Date().getTime()-((Wt=pn.current)==null?void 0:Wt.getTime()),me=ct==="x"?ie:wa,il=Math.abs(me)/Ht;if(Math.abs(me)>=Pv||il>.11){Ze(ua.current),h.onDismiss==null||h.onDismiss.call(h,h),dt(ct==="x"?ie>0?"right":"left":wa>0?"down":"up"),Ie(),Ae(!0);return}else{var ye,ve;(ye=Oe.current)==null||ye.style.setProperty("--swipe-amount-x","0px"),(ve=Oe.current)==null||ve.style.setProperty("--swipe-amount-y","0px")}se(!1),ht(!1),et(null)},onPointerMove:F=>{var Ut,Wt,ie;if(!Oa.current||!Ma||((Ut=window.getSelection())==null?void 0:Ut.toString().length)>0)return;const Ht=F.clientY-Oa.current.y,me=F.clientX-Oa.current.x;var il;const ye=(il=u.swipeDirections)!=null?il:eg(kt);!ct&&(Math.abs(me)>1||Math.abs(Ht)>1)&&et(Math.abs(me)>Math.abs(Ht)?"x":"y");let ve={x:0,y:0};const wl=Je=>1/(1.5+Math.abs(Je)/20);if(ct==="y"){if(ye.includes("top")||ye.includes("bottom"))if(ye.includes("top")&&Ht<0||ye.includes("bottom")&&Ht>0)ve.y=Ht;else{const Je=Ht*wl(Ht);ve.y=Math.abs(Je)0)ve.x=me;else{const Je=me*wl(me);ve.x=Math.abs(Je)0||Math.abs(ve.y)>0)&&se(!0),(Wt=Oe.current)==null||Wt.style.setProperty("--swipe-amount-x",`${ve.x}px`),(ie=Oe.current)==null||ie.style.setProperty("--swipe-amount-y",`${ve.y}px`)}},bi&&!h.jsx&&ce!=="loading"?_.createElement("button",{"aria-label":D,"data-disabled":zn,"data-close-button":!0,onClick:zn||!Ma?()=>{}:()=>{Ie(),h.onDismiss==null||h.onDismiss.call(h,h)},className:na(S?.closeButton,h==null||(r=h.classNames)==null?void 0:r.closeButton)},(Pe=N?.close)!=null?Pe:Yv):null,(ce||h.icon||h.promise)&&h.icon!==null&&(N?.[ce]!==null||h.icon)?_.createElement("div",{"data-icon":"",className:na(S?.icon,h==null||(y=h.classNames)==null?void 0:y.icon)},h.promise||h.type==="loading"&&!h.icon?h.icon||Ml():null,h.type!=="loading"?Ol:null):null,_.createElement("div",{"data-content":"",className:na(S?.content,h==null||(v=h.classNames)==null?void 0:v.content)},_.createElement("div",{"data-title":"",className:na(S?.title,h==null||(T=h.classNames)==null?void 0:T.title)},h.jsx?h.jsx:typeof h.title=="function"?h.title():h.title),h.description?_.createElement("div",{"data-description":"",className:na(Gt,Gu,S?.description,h==null||(E=h.classNames)==null?void 0:E.description)},typeof h.description=="function"?h.description():h.description):null),_.isValidElement(h.cancel)?h.cancel:h.cancel&&Ru(h.cancel)?_.createElement("button",{"data-button":!0,"data-cancel":!0,style:h.cancelButtonStyle||q,onClick:F=>{Ru(h.cancel)&&Ma&&(h.cancel.onClick==null||h.cancel.onClick.call(h.cancel,F),Ie())},className:na(S?.cancelButton,h==null||(O=h.classNames)==null?void 0:O.cancelButton)},h.cancel.label):null,_.isValidElement(h.action)?h.action:h.action&&Ru(h.action)?_.createElement("button",{"data-button":!0,"data-action":!0,style:h.actionButtonStyle||Ot,onClick:F=>{Ru(h.action)&&(h.action.onClick==null||h.action.onClick.call(h.action,F),!F.defaultPrevented&&Ie())},className:na(S?.actionButton,h==null||(C=h.classNames)==null?void 0:C.actionButton)},h.action.label):null)};function Nh(){if(typeof window>"u"||typeof document>"u")return"ltr";const u=document.documentElement.getAttribute("dir");return u==="auto"||!u?window.getComputedStyle(document.documentElement).direction:u}function lg(u,c){const o={};return[u,c].forEach((r,y)=>{const v=y===1,T=v?"--mobile-offset":"--offset",E=v?Wv:Fv;function O(C){["top","right","bottom","left"].forEach(H=>{o[`${T}-${H}`]=typeof C=="number"?`${C}px`:C})}typeof r=="number"||typeof r=="string"?O(r):typeof r=="object"?["top","right","bottom","left"].forEach(C=>{r[C]===void 0?o[`${T}-${C}`]=E:o[`${T}-${C}`]=typeof r[C]=="number"?`${r[C]}px`:r[C]}):O(E)}),o}const ng=_.forwardRef(function(c,o){const{id:r,invert:y,position:v="bottom-right",hotkey:T=["altKey","KeyT"],expand:E,closeButton:O,className:C,offset:H,mobileOffset:h,theme:R="light",richColors:K,duration:B,style:L,visibleToasts:P=kv,toastOptions:X,dir:St=Nh(),gap:st=Iv,icons:Tt,containerAriaLabel:at="Notifications"}=c,[k,At]=_.useState([]),q=_.useMemo(()=>r?k.filter(U=>U.toasterId===r):k.filter(U=>!U.toasterId),[k,r]),Ot=_.useMemo(()=>Array.from(new Set([v].concat(q.filter(U=>U.position).map(U=>U.position)))),[q,v]),[ue,Gt]=_.useState([]),[Dt,kt]=_.useState(!1),[he,Bt]=_.useState(!1),[S,N]=_.useState(R!=="system"?R:typeof window<"u"&&window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),D=_.useRef(null),ct=T.join("+").replace(/Key/g,"").replace(/Digit/g,""),et=_.useRef(null),wt=_.useRef(!1),dt=_.useCallback(U=>{At(Z=>{var nt;return(nt=Z.find(_t=>_t.id===U.id))!=null&&nt.delete||Te.dismiss(U.id),Z.filter(({id:_t})=>_t!==U.id)})},[]);return _.useEffect(()=>Te.subscribe(U=>{if(U.dismiss){requestAnimationFrame(()=>{At(Z=>Z.map(nt=>nt.id===U.id?{...nt,delete:!0}:nt))});return}setTimeout(()=>{Sy.flushSync(()=>{At(Z=>{const nt=Z.findIndex(_t=>_t.id===U.id);return nt!==-1?[...Z.slice(0,nt),{...Z[nt],...U},...Z.slice(nt+1)]:[U,...Z]})})})}),[k]),_.useEffect(()=>{if(R!=="system"){N(R);return}if(R==="system"&&(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?N("dark"):N("light")),typeof window>"u")return;const U=window.matchMedia("(prefers-color-scheme: dark)");try{U.addEventListener("change",({matches:Z})=>{N(Z?"dark":"light")})}catch{U.addListener(({matches:nt})=>{try{N(nt?"dark":"light")}catch(_t){console.error(_t)}})}},[R]),_.useEffect(()=>{k.length<=1&&kt(!1)},[k]),_.useEffect(()=>{const U=Z=>{var nt;if(T.every(ht=>Z[ht]||Z.code===ht)){var gt;kt(!0),(gt=D.current)==null||gt.focus()}Z.code==="Escape"&&(document.activeElement===D.current||(nt=D.current)!=null&&nt.contains(document.activeElement))&&kt(!1)};return document.addEventListener("keydown",U),()=>document.removeEventListener("keydown",U)},[T]),_.useEffect(()=>{if(D.current)return()=>{et.current&&(et.current.focus({preventScroll:!0}),et.current=null,wt.current=!1)}},[D.current]),_.createElement("section",{ref:o,"aria-label":`${at} ${ct}`,tabIndex:-1,"aria-live":"polite","aria-relevant":"additions text","aria-atomic":"false",suppressHydrationWarning:!0},Ot.map((U,Z)=>{var nt;const[_t,gt]=U.split("-");return q.length?_.createElement("ol",{key:U,dir:St==="auto"?Nh():St,tabIndex:-1,ref:D,className:C,"data-sonner-toaster":!0,"data-sonner-theme":S,"data-y-position":_t,"data-x-position":gt,style:{"--front-toast-height":`${((nt=ue[0])==null?void 0:nt.height)||0}px`,"--width":`${$v}px`,"--gap":`${st}px`,...L,...lg(H,h)},onBlur:ht=>{wt.current&&!ht.currentTarget.contains(ht.relatedTarget)&&(wt.current=!1,et.current&&(et.current.focus({preventScroll:!0}),et.current=null))},onFocus:ht=>{ht.target instanceof HTMLElement&&ht.target.dataset.dismissible==="false"||wt.current||(wt.current=!0,et.current=ht.relatedTarget)},onMouseEnter:()=>kt(!0),onMouseMove:()=>kt(!0),onMouseLeave:()=>{he||kt(!1)},onDragEnd:()=>kt(!1),onPointerDown:ht=>{ht.target instanceof HTMLElement&&ht.target.dataset.dismissible==="false"||Bt(!0)},onPointerUp:()=>Bt(!1)},q.filter(ht=>!ht.position&&Z===0||ht.position===U).map((ht,Ft)=>{var Ae,Me;return _.createElement(ag,{key:ht.id,icons:Tt,index:Ft,toast:ht,defaultRichColors:K,duration:(Ae=X?.duration)!=null?Ae:B,className:X?.className,descriptionClassName:X?.descriptionClassName,invert:y,visibleToasts:P,closeButton:(Me=X?.closeButton)!=null?Me:O,interacting:he,position:U,style:X?.style,unstyled:X?.unstyled,classNames:X?.classNames,cancelButtonStyle:X?.cancelButtonStyle,actionButtonStyle:X?.actionButtonStyle,closeButtonAriaLabel:X?.closeButtonAriaLabel,removeToast:dt,toasts:q.filter(se=>se.position==ht.position),heights:ue.filter(se=>se.position==ht.position),setHeights:Gt,expandByDefault:E,gap:st,expanded:Dt,swipeDirections:c.swipeDirections})})):null}))}),ig=({...u})=>{const{theme:c="system"}=ov();return I.jsx(ng,{theme:c,className:"toaster group",icons:{success:I.jsx(Ev,{className:"size-4"}),info:I.jsx(Av,{className:"size-4"}),warning:I.jsx(Nv,{className:"size-4"}),error:I.jsx(Dv,{className:"size-4"}),loading:I.jsx(Ov,{className:"size-4 animate-spin"})},style:{"--normal-bg":"var(--popover)","--normal-text":"var(--popover-foreground)","--normal-border":"var(--border)","--border-radius":"var(--radius)"},...u})},ug=new lv,sg=({children:u})=>I.jsx(iv,{client:ug,children:I.jsxs(vv,{defaultTheme:"system",storageKey:"dragon-theme",children:[u,I.jsx(ig,{richColors:!0,expand:!0,position:"top-center"})]})});function Fh(u){var c,o,r="";if(typeof u=="string"||typeof u=="number")r+=u;else if(typeof u=="object")if(Array.isArray(u)){var y=u.length;for(c=0;c{const c=rg(u),{conflictingClassGroups:o,conflictingClassGroupModifiers:r}=u;return{getClassGroupId:T=>{const E=T.split(xo);return E[0]===""&&E.length!==1&&E.shift(),$h(E,c)||og(T)},getConflictingClassGroupIds:(T,E)=>{const O=o[T]||[];return E&&r[T]?[...O,...r[T]]:O}}},$h=(u,c)=>{if(u.length===0)return c.classGroupId;const o=u[0],r=c.nextPart.get(o),y=r?$h(u.slice(1),r):void 0;if(y)return y;if(c.validators.length===0)return;const v=u.join(xo);return c.validators.find(({validator:T})=>T(v))?.classGroupId},_h=/^\[(.+)\]$/,og=u=>{if(_h.test(u)){const c=_h.exec(u)[1],o=c?.substring(0,c.indexOf(":"));if(o)return"arbitrary.."+o}},rg=u=>{const{theme:c,classGroups:o}=u,r={nextPart:new Map,validators:[]};for(const y in o)fo(o[y],r,y,c);return r},fo=(u,c,o,r)=>{u.forEach(y=>{if(typeof y=="string"){const v=y===""?c:Uh(c,y);v.classGroupId=o;return}if(typeof y=="function"){if(fg(y)){fo(y(r),c,o,r);return}c.validators.push({validator:y,classGroupId:o});return}Object.entries(y).forEach(([v,T])=>{fo(T,Uh(c,v),o,r)})})},Uh=(u,c)=>{let o=u;return c.split(xo).forEach(r=>{o.nextPart.has(r)||o.nextPart.set(r,{nextPart:new Map,validators:[]}),o=o.nextPart.get(r)}),o},fg=u=>u.isThemeGetter,dg=u=>{if(u<1)return{get:()=>{},set:()=>{}};let c=0,o=new Map,r=new Map;const y=(v,T)=>{o.set(v,T),c++,c>u&&(c=0,r=o,o=new Map)};return{get(v){let T=o.get(v);if(T!==void 0)return T;if((T=r.get(v))!==void 0)return y(v,T),T},set(v,T){o.has(v)?o.set(v,T):y(v,T)}}},ho="!",mo=":",hg=mo.length,mg=u=>{const{prefix:c,experimentalParseClassName:o}=u;let r=y=>{const v=[];let T=0,E=0,O=0,C;for(let B=0;BO?C-O:void 0;return{modifiers:v,hasImportantModifier:R,baseClassName:h,maybePostfixModifierPosition:K}};if(c){const y=c+mo,v=r;r=T=>T.startsWith(y)?v(T.substring(y.length)):{isExternal:!0,modifiers:[],hasImportantModifier:!1,baseClassName:T,maybePostfixModifierPosition:void 0}}if(o){const y=r;r=v=>o({className:v,parseClassName:y})}return r},yg=u=>u.endsWith(ho)?u.substring(0,u.length-1):u.startsWith(ho)?u.substring(1):u,vg=u=>{const c=Object.fromEntries(u.orderSensitiveModifiers.map(r=>[r,!0]));return r=>{if(r.length<=1)return r;const y=[];let v=[];return r.forEach(T=>{T[0]==="["||c[T]?(y.push(...v.sort(),T),v=[]):v.push(T)}),y.push(...v.sort()),y}},gg=u=>({cache:dg(u.cacheSize),parseClassName:mg(u),sortModifiers:vg(u),...cg(u)}),pg=/\s+/,bg=(u,c)=>{const{parseClassName:o,getClassGroupId:r,getConflictingClassGroupIds:y,sortModifiers:v}=c,T=[],E=u.trim().split(pg);let O="";for(let C=E.length-1;C>=0;C-=1){const H=E[C],{isExternal:h,modifiers:R,hasImportantModifier:K,baseClassName:B,maybePostfixModifierPosition:L}=o(H);if(h){O=H+(O.length>0?" "+O:O);continue}let P=!!L,X=r(P?B.substring(0,L):B);if(!X){if(!P){O=H+(O.length>0?" "+O:O);continue}if(X=r(B),!X){O=H+(O.length>0?" "+O:O);continue}P=!1}const St=v(R).join(":"),st=K?St+ho:St,Tt=st+X;if(T.includes(Tt))continue;T.push(Tt);const at=y(X,P);for(let k=0;k0?" "+O:O)}return O};function Sg(){let u=0,c,o,r="";for(;u{if(typeof u=="string")return u;let c,o="";for(let r=0;rh(H),u());return o=gg(C),r=o.cache.get,y=o.cache.set,v=E,E(O)}function E(O){const C=r(O);if(C)return C;const H=bg(O,o);return y(O,H),H}return function(){return v(Sg.apply(null,arguments))}}const Jt=u=>{const c=o=>o[u]||[];return c.isThemeGetter=!0,c},Ph=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,tm=/^\((?:(\w[\w-]*):)?(.+)\)$/i,zg=/^\d+\/\d+$/,Eg=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Tg=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,Ag=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Mg=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Og=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,mn=u=>zg.test(u),lt=u=>!!u&&!Number.isNaN(Number(u)),Pa=u=>!!u&&Number.isInteger(Number(u)),no=u=>u.endsWith("%")&<(u.slice(0,-1)),Aa=u=>Eg.test(u),wg=()=>!0,Dg=u=>Tg.test(u)&&!Ag.test(u),em=()=>!1,Cg=u=>Mg.test(u),Ng=u=>Og.test(u),_g=u=>!Q(u)&&!Y(u),Ug=u=>yn(u,nm,em),Q=u=>Ph.test(u),El=u=>yn(u,im,Dg),io=u=>yn(u,jg,lt),Rh=u=>yn(u,am,em),Rg=u=>yn(u,lm,Ng),Hu=u=>yn(u,um,Cg),Y=u=>tm.test(u),mi=u=>vn(u,im),Hg=u=>vn(u,Qg),Hh=u=>vn(u,am),Bg=u=>vn(u,nm),qg=u=>vn(u,lm),Bu=u=>vn(u,um,!0),yn=(u,c,o)=>{const r=Ph.exec(u);return r?r[1]?c(r[1]):o(r[2]):!1},vn=(u,c,o=!1)=>{const r=tm.exec(u);return r?r[1]?c(r[1]):o:!1},am=u=>u==="position"||u==="percentage",lm=u=>u==="image"||u==="url",nm=u=>u==="length"||u==="size"||u==="bg-size",im=u=>u==="length",jg=u=>u==="number",Qg=u=>u==="family-name",um=u=>u==="shadow",Yg=()=>{const u=Jt("color"),c=Jt("font"),o=Jt("text"),r=Jt("font-weight"),y=Jt("tracking"),v=Jt("leading"),T=Jt("breakpoint"),E=Jt("container"),O=Jt("spacing"),C=Jt("radius"),H=Jt("shadow"),h=Jt("inset-shadow"),R=Jt("text-shadow"),K=Jt("drop-shadow"),B=Jt("blur"),L=Jt("perspective"),P=Jt("aspect"),X=Jt("ease"),St=Jt("animate"),st=()=>["auto","avoid","all","avoid-page","page","left","right","column"],Tt=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],at=()=>[...Tt(),Y,Q],k=()=>["auto","hidden","clip","visible","scroll"],At=()=>["auto","contain","none"],q=()=>[Y,Q,O],Ot=()=>[mn,"full","auto",...q()],ue=()=>[Pa,"none","subgrid",Y,Q],Gt=()=>["auto",{span:["full",Pa,Y,Q]},Pa,Y,Q],Dt=()=>[Pa,"auto",Y,Q],kt=()=>["auto","min","max","fr",Y,Q],he=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],Bt=()=>["start","end","center","stretch","center-safe","end-safe"],S=()=>["auto",...q()],N=()=>[mn,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...q()],D=()=>[u,Y,Q],ct=()=>[...Tt(),Hh,Rh,{position:[Y,Q]}],et=()=>["no-repeat",{repeat:["","x","y","space","round"]}],wt=()=>["auto","cover","contain",Bg,Ug,{size:[Y,Q]}],dt=()=>[no,mi,El],U=()=>["","none","full",C,Y,Q],Z=()=>["",lt,mi,El],nt=()=>["solid","dashed","dotted","double"],_t=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],gt=()=>[lt,no,Hh,Rh],ht=()=>["","none",B,Y,Q],Ft=()=>["none",lt,Y,Q],Ae=()=>["none",lt,Y,Q],Me=()=>[lt,Y,Q],se=()=>[mn,"full",...q()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[Aa],breakpoint:[Aa],color:[wg],container:[Aa],"drop-shadow":[Aa],ease:["in","out","in-out"],font:[_g],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[Aa],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[Aa],shadow:[Aa],spacing:["px",lt],text:[Aa],"text-shadow":[Aa],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",mn,Q,Y,P]}],container:["container"],columns:[{columns:[lt,Q,Y,E]}],"break-after":[{"break-after":st()}],"break-before":[{"break-before":st()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:at()}],overflow:[{overflow:k()}],"overflow-x":[{"overflow-x":k()}],"overflow-y":[{"overflow-y":k()}],overscroll:[{overscroll:At()}],"overscroll-x":[{"overscroll-x":At()}],"overscroll-y":[{"overscroll-y":At()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:Ot()}],"inset-x":[{"inset-x":Ot()}],"inset-y":[{"inset-y":Ot()}],start:[{start:Ot()}],end:[{end:Ot()}],top:[{top:Ot()}],right:[{right:Ot()}],bottom:[{bottom:Ot()}],left:[{left:Ot()}],visibility:["visible","invisible","collapse"],z:[{z:[Pa,"auto",Y,Q]}],basis:[{basis:[mn,"full","auto",E,...q()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[lt,mn,"auto","initial","none",Q]}],grow:[{grow:["",lt,Y,Q]}],shrink:[{shrink:["",lt,Y,Q]}],order:[{order:[Pa,"first","last","none",Y,Q]}],"grid-cols":[{"grid-cols":ue()}],"col-start-end":[{col:Gt()}],"col-start":[{"col-start":Dt()}],"col-end":[{"col-end":Dt()}],"grid-rows":[{"grid-rows":ue()}],"row-start-end":[{row:Gt()}],"row-start":[{"row-start":Dt()}],"row-end":[{"row-end":Dt()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":kt()}],"auto-rows":[{"auto-rows":kt()}],gap:[{gap:q()}],"gap-x":[{"gap-x":q()}],"gap-y":[{"gap-y":q()}],"justify-content":[{justify:[...he(),"normal"]}],"justify-items":[{"justify-items":[...Bt(),"normal"]}],"justify-self":[{"justify-self":["auto",...Bt()]}],"align-content":[{content:["normal",...he()]}],"align-items":[{items:[...Bt(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...Bt(),{baseline:["","last"]}]}],"place-content":[{"place-content":he()}],"place-items":[{"place-items":[...Bt(),"baseline"]}],"place-self":[{"place-self":["auto",...Bt()]}],p:[{p:q()}],px:[{px:q()}],py:[{py:q()}],ps:[{ps:q()}],pe:[{pe:q()}],pt:[{pt:q()}],pr:[{pr:q()}],pb:[{pb:q()}],pl:[{pl:q()}],m:[{m:S()}],mx:[{mx:S()}],my:[{my:S()}],ms:[{ms:S()}],me:[{me:S()}],mt:[{mt:S()}],mr:[{mr:S()}],mb:[{mb:S()}],ml:[{ml:S()}],"space-x":[{"space-x":q()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":q()}],"space-y-reverse":["space-y-reverse"],size:[{size:N()}],w:[{w:[E,"screen",...N()]}],"min-w":[{"min-w":[E,"screen","none",...N()]}],"max-w":[{"max-w":[E,"screen","none","prose",{screen:[T]},...N()]}],h:[{h:["screen","lh",...N()]}],"min-h":[{"min-h":["screen","lh","none",...N()]}],"max-h":[{"max-h":["screen","lh",...N()]}],"font-size":[{text:["base",o,mi,El]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[r,Y,io]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",no,Q]}],"font-family":[{font:[Hg,Q,c]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[y,Y,Q]}],"line-clamp":[{"line-clamp":[lt,"none",Y,io]}],leading:[{leading:[v,...q()]}],"list-image":[{"list-image":["none",Y,Q]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",Y,Q]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:D()}],"text-color":[{text:D()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...nt(),"wavy"]}],"text-decoration-thickness":[{decoration:[lt,"from-font","auto",Y,El]}],"text-decoration-color":[{decoration:D()}],"underline-offset":[{"underline-offset":[lt,"auto",Y,Q]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:q()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",Y,Q]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",Y,Q]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:ct()}],"bg-repeat":[{bg:et()}],"bg-size":[{bg:wt()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},Pa,Y,Q],radial:["",Y,Q],conic:[Pa,Y,Q]},qg,Rg]}],"bg-color":[{bg:D()}],"gradient-from-pos":[{from:dt()}],"gradient-via-pos":[{via:dt()}],"gradient-to-pos":[{to:dt()}],"gradient-from":[{from:D()}],"gradient-via":[{via:D()}],"gradient-to":[{to:D()}],rounded:[{rounded:U()}],"rounded-s":[{"rounded-s":U()}],"rounded-e":[{"rounded-e":U()}],"rounded-t":[{"rounded-t":U()}],"rounded-r":[{"rounded-r":U()}],"rounded-b":[{"rounded-b":U()}],"rounded-l":[{"rounded-l":U()}],"rounded-ss":[{"rounded-ss":U()}],"rounded-se":[{"rounded-se":U()}],"rounded-ee":[{"rounded-ee":U()}],"rounded-es":[{"rounded-es":U()}],"rounded-tl":[{"rounded-tl":U()}],"rounded-tr":[{"rounded-tr":U()}],"rounded-br":[{"rounded-br":U()}],"rounded-bl":[{"rounded-bl":U()}],"border-w":[{border:Z()}],"border-w-x":[{"border-x":Z()}],"border-w-y":[{"border-y":Z()}],"border-w-s":[{"border-s":Z()}],"border-w-e":[{"border-e":Z()}],"border-w-t":[{"border-t":Z()}],"border-w-r":[{"border-r":Z()}],"border-w-b":[{"border-b":Z()}],"border-w-l":[{"border-l":Z()}],"divide-x":[{"divide-x":Z()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":Z()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...nt(),"hidden","none"]}],"divide-style":[{divide:[...nt(),"hidden","none"]}],"border-color":[{border:D()}],"border-color-x":[{"border-x":D()}],"border-color-y":[{"border-y":D()}],"border-color-s":[{"border-s":D()}],"border-color-e":[{"border-e":D()}],"border-color-t":[{"border-t":D()}],"border-color-r":[{"border-r":D()}],"border-color-b":[{"border-b":D()}],"border-color-l":[{"border-l":D()}],"divide-color":[{divide:D()}],"outline-style":[{outline:[...nt(),"none","hidden"]}],"outline-offset":[{"outline-offset":[lt,Y,Q]}],"outline-w":[{outline:["",lt,mi,El]}],"outline-color":[{outline:D()}],shadow:[{shadow:["","none",H,Bu,Hu]}],"shadow-color":[{shadow:D()}],"inset-shadow":[{"inset-shadow":["none",h,Bu,Hu]}],"inset-shadow-color":[{"inset-shadow":D()}],"ring-w":[{ring:Z()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:D()}],"ring-offset-w":[{"ring-offset":[lt,El]}],"ring-offset-color":[{"ring-offset":D()}],"inset-ring-w":[{"inset-ring":Z()}],"inset-ring-color":[{"inset-ring":D()}],"text-shadow":[{"text-shadow":["none",R,Bu,Hu]}],"text-shadow-color":[{"text-shadow":D()}],opacity:[{opacity:[lt,Y,Q]}],"mix-blend":[{"mix-blend":[..._t(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":_t()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[lt]}],"mask-image-linear-from-pos":[{"mask-linear-from":gt()}],"mask-image-linear-to-pos":[{"mask-linear-to":gt()}],"mask-image-linear-from-color":[{"mask-linear-from":D()}],"mask-image-linear-to-color":[{"mask-linear-to":D()}],"mask-image-t-from-pos":[{"mask-t-from":gt()}],"mask-image-t-to-pos":[{"mask-t-to":gt()}],"mask-image-t-from-color":[{"mask-t-from":D()}],"mask-image-t-to-color":[{"mask-t-to":D()}],"mask-image-r-from-pos":[{"mask-r-from":gt()}],"mask-image-r-to-pos":[{"mask-r-to":gt()}],"mask-image-r-from-color":[{"mask-r-from":D()}],"mask-image-r-to-color":[{"mask-r-to":D()}],"mask-image-b-from-pos":[{"mask-b-from":gt()}],"mask-image-b-to-pos":[{"mask-b-to":gt()}],"mask-image-b-from-color":[{"mask-b-from":D()}],"mask-image-b-to-color":[{"mask-b-to":D()}],"mask-image-l-from-pos":[{"mask-l-from":gt()}],"mask-image-l-to-pos":[{"mask-l-to":gt()}],"mask-image-l-from-color":[{"mask-l-from":D()}],"mask-image-l-to-color":[{"mask-l-to":D()}],"mask-image-x-from-pos":[{"mask-x-from":gt()}],"mask-image-x-to-pos":[{"mask-x-to":gt()}],"mask-image-x-from-color":[{"mask-x-from":D()}],"mask-image-x-to-color":[{"mask-x-to":D()}],"mask-image-y-from-pos":[{"mask-y-from":gt()}],"mask-image-y-to-pos":[{"mask-y-to":gt()}],"mask-image-y-from-color":[{"mask-y-from":D()}],"mask-image-y-to-color":[{"mask-y-to":D()}],"mask-image-radial":[{"mask-radial":[Y,Q]}],"mask-image-radial-from-pos":[{"mask-radial-from":gt()}],"mask-image-radial-to-pos":[{"mask-radial-to":gt()}],"mask-image-radial-from-color":[{"mask-radial-from":D()}],"mask-image-radial-to-color":[{"mask-radial-to":D()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":Tt()}],"mask-image-conic-pos":[{"mask-conic":[lt]}],"mask-image-conic-from-pos":[{"mask-conic-from":gt()}],"mask-image-conic-to-pos":[{"mask-conic-to":gt()}],"mask-image-conic-from-color":[{"mask-conic-from":D()}],"mask-image-conic-to-color":[{"mask-conic-to":D()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:ct()}],"mask-repeat":[{mask:et()}],"mask-size":[{mask:wt()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",Y,Q]}],filter:[{filter:["","none",Y,Q]}],blur:[{blur:ht()}],brightness:[{brightness:[lt,Y,Q]}],contrast:[{contrast:[lt,Y,Q]}],"drop-shadow":[{"drop-shadow":["","none",K,Bu,Hu]}],"drop-shadow-color":[{"drop-shadow":D()}],grayscale:[{grayscale:["",lt,Y,Q]}],"hue-rotate":[{"hue-rotate":[lt,Y,Q]}],invert:[{invert:["",lt,Y,Q]}],saturate:[{saturate:[lt,Y,Q]}],sepia:[{sepia:["",lt,Y,Q]}],"backdrop-filter":[{"backdrop-filter":["","none",Y,Q]}],"backdrop-blur":[{"backdrop-blur":ht()}],"backdrop-brightness":[{"backdrop-brightness":[lt,Y,Q]}],"backdrop-contrast":[{"backdrop-contrast":[lt,Y,Q]}],"backdrop-grayscale":[{"backdrop-grayscale":["",lt,Y,Q]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[lt,Y,Q]}],"backdrop-invert":[{"backdrop-invert":["",lt,Y,Q]}],"backdrop-opacity":[{"backdrop-opacity":[lt,Y,Q]}],"backdrop-saturate":[{"backdrop-saturate":[lt,Y,Q]}],"backdrop-sepia":[{"backdrop-sepia":["",lt,Y,Q]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":q()}],"border-spacing-x":[{"border-spacing-x":q()}],"border-spacing-y":[{"border-spacing-y":q()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",Y,Q]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[lt,"initial",Y,Q]}],ease:[{ease:["linear","initial",X,Y,Q]}],delay:[{delay:[lt,Y,Q]}],animate:[{animate:["none",St,Y,Q]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[L,Y,Q]}],"perspective-origin":[{"perspective-origin":at()}],rotate:[{rotate:Ft()}],"rotate-x":[{"rotate-x":Ft()}],"rotate-y":[{"rotate-y":Ft()}],"rotate-z":[{"rotate-z":Ft()}],scale:[{scale:Ae()}],"scale-x":[{"scale-x":Ae()}],"scale-y":[{"scale-y":Ae()}],"scale-z":[{"scale-z":Ae()}],"scale-3d":["scale-3d"],skew:[{skew:Me()}],"skew-x":[{"skew-x":Me()}],"skew-y":[{"skew-y":Me()}],transform:[{transform:[Y,Q,"","none","gpu","cpu"]}],"transform-origin":[{origin:at()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:se()}],"translate-x":[{"translate-x":se()}],"translate-y":[{"translate-y":se()}],"translate-z":[{"translate-z":se()}],"translate-none":["translate-none"],accent:[{accent:D()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:D()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",Y,Q]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":q()}],"scroll-mx":[{"scroll-mx":q()}],"scroll-my":[{"scroll-my":q()}],"scroll-ms":[{"scroll-ms":q()}],"scroll-me":[{"scroll-me":q()}],"scroll-mt":[{"scroll-mt":q()}],"scroll-mr":[{"scroll-mr":q()}],"scroll-mb":[{"scroll-mb":q()}],"scroll-ml":[{"scroll-ml":q()}],"scroll-p":[{"scroll-p":q()}],"scroll-px":[{"scroll-px":q()}],"scroll-py":[{"scroll-py":q()}],"scroll-ps":[{"scroll-ps":q()}],"scroll-pe":[{"scroll-pe":q()}],"scroll-pt":[{"scroll-pt":q()}],"scroll-pr":[{"scroll-pr":q()}],"scroll-pb":[{"scroll-pb":q()}],"scroll-pl":[{"scroll-pl":q()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",Y,Q]}],fill:[{fill:["none",...D()]}],"stroke-w":[{stroke:[lt,mi,El,io]}],stroke:[{stroke:["none",...D()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},Gg=xg(Yg);function Tl(...u){return Gg(Wh(u))}function Xg({className:u,...c}){return I.jsx("div",{"data-slot":"card",className:Tl("bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",u),...c})}function Lg({className:u,...c}){return I.jsx("div",{"data-slot":"card-header",className:Tl("@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",u),...c})}function Vg({className:u,...c}){return I.jsx("div",{"data-slot":"card-title",className:Tl("leading-none font-semibold",u),...c})}function Zg({className:u,...c}){return I.jsx("div",{"data-slot":"card-description",className:Tl("text-muted-foreground text-sm",u),...c})}function Kg({className:u,...c}){return I.jsx("div",{"data-slot":"card-content",className:Tl("px-6",u),...c})}function Bh(u,c){if(typeof u=="function")return u(c);u!=null&&(u.current=c)}function Jg(...u){return c=>{let o=!1;const r=u.map(y=>{const v=Bh(y,c);return!o&&typeof v=="function"&&(o=!0),v});if(o)return()=>{for(let y=0;y{const{children:v,...T}=r,E=W.Children.toArray(v),O=E.find(Ig);if(O){const C=O.props.children,H=E.map(h=>h===O?W.Children.count(C)>1?W.Children.only(null):W.isValidElement(C)?C.props.children:null:h);return I.jsx(c,{...T,ref:y,children:W.isValidElement(C)?W.cloneElement(C,void 0,H):null})}return I.jsx(c,{...T,ref:y,children:v})});return o.displayName=`${u}.Slot`,o}var Fg=kg("Slot");function Wg(u){const c=W.forwardRef((o,r)=>{const{children:y,...v}=o;if(W.isValidElement(y)){const T=tp(y),E=Pg(v,y.props);return y.type!==W.Fragment&&(E.ref=r?Jg(r,T):T),W.cloneElement(y,E)}return W.Children.count(y)>1?W.Children.only(null):null});return c.displayName=`${u}.SlotClone`,c}var $g=Symbol("radix.slottable");function Ig(u){return W.isValidElement(u)&&typeof u.type=="function"&&"__radixId"in u.type&&u.type.__radixId===$g}function Pg(u,c){const o={...c};for(const r in c){const y=u[r],v=c[r];/^on[A-Z]/.test(r)?y&&v?o[r]=(...E)=>{const O=v(...E);return y(...E),O}:y&&(o[r]=y):r==="style"?o[r]={...y,...v}:r==="className"&&(o[r]=[y,v].filter(Boolean).join(" "))}return{...u,...o}}function tp(u){let c=Object.getOwnPropertyDescriptor(u.props,"ref")?.get,o=c&&"isReactWarning"in c&&c.isReactWarning;return o?u.ref:(c=Object.getOwnPropertyDescriptor(u,"ref")?.get,o=c&&"isReactWarning"in c&&c.isReactWarning,o?u.props.ref:u.props.ref||u.ref)}const qh=u=>typeof u=="boolean"?`${u}`:u===0?"0":u,jh=Wh,ep=(u,c)=>o=>{var r;if(c?.variants==null)return jh(u,o?.class,o?.className);const{variants:y,defaultVariants:v}=c,T=Object.keys(y).map(C=>{const H=o?.[C],h=v?.[C];if(H===null)return null;const R=qh(H)||qh(h);return y[C][R]}),E=o&&Object.entries(o).reduce((C,H)=>{let[h,R]=H;return R===void 0||(C[h]=R),C},{}),O=c==null||(r=c.compoundVariants)===null||r===void 0?void 0:r.reduce((C,H)=>{let{class:h,className:R,...K}=H;return Object.entries(K).every(B=>{let[L,P]=B;return Array.isArray(P)?P.includes({...v,...E}[L]):{...v,...E}[L]===P})?[...C,h,R]:C},[]);return jh(u,T,O,o?.class,o?.className)},ap=ep("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",outline:"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2 has-[>svg]:px-3",sm:"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",lg:"h-10 rounded-md px-6 has-[>svg]:px-4",icon:"size-9","icon-sm":"size-8","icon-lg":"size-10"}},defaultVariants:{variant:"default",size:"default"}});function lp({className:u,variant:c,size:o,asChild:r=!1,...y}){const v=r?Fg:"button";return I.jsx(v,{"data-slot":"button",className:Tl(ap({variant:c,size:o,className:u})),...y})}const ju="autoglue.tokens",yo="autoglue.auth-change";let ia=vo();function vo(){try{const u=localStorage.getItem(ju);return u?JSON.parse(u):null}catch{return null}}function np(u){u?localStorage.setItem(ju,JSON.stringify(u)):localStorage.removeItem(ju)}function ip(u){window.dispatchEvent(new CustomEvent(yo,{detail:u}))}const go={get(){return ia},set(u){ia=u,np(u),ip(u)},reload(){return ia=vo(),ia},isAuthed(){return!!ia?.access_token},getAccessToken(){return ia?.access_token??null},isExpired(u=Math.floor(Date.now()/1e3)){const c=Qh(ia?.access_token);return c!==null?u>=c:!0},willExpireSoon(u=60,c=Math.floor(Date.now()/1e3)){const o=Qh(ia?.access_token);return o!==null?o-c<=u:!0},logout(){go.set(null)},subscribe(u){const c=r=>u(r.detail??null),o=r=>{r.key===ju&&(ia=vo(),u(ia))};return window.addEventListener(yo,c),window.addEventListener("storage",o),()=>{window.removeEventListener(yo,c),window.removeEventListener("storage",o)}}};function Qh(u){if(!u)return null;const c=u.split(".");if(c.length<2)return null;try{const o=JSON.parse(atob(up(c[1])));return(typeof o?.exp=="number"?o.exp:null)??null}catch{return null}}function up(u){return u.replace(/-/g,"+").replace(/_/g,"/")+"==".slice((2-u.length*3%4)%4)}const sp="autoglue.org";localStorage.getItem(sp);const cp="/api/v1";function op(u,c="gsot-auth",o=520,r=640){const y=window.top.outerHeight/2+window.top.screenY-r/2,v=window.top.outerWidth/2+window.top.screenX-o/2;return window.open(u,c,`toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=${o},height=${r},top=${y},left=${v}`)}async function rp(u){const c=new URLSearchParams({mode:"spa",origin:window.location.origin}),o=await fetch(`${cp}/auth/${u}/start?`+c,{method:"POST"});if(!o.ok)throw new Error("Failed to start auth");return(await o.json()).auth_url}const Yh=()=>{const u=xy(),c=zy(),o=W.useMemo(()=>{const y=new URLSearchParams(c.search).get("to")||"/me";try{const v=new URL(y,window.location.origin);return v.origin===window.location.origin?v.pathname+v.search:"/me"}catch{return"/me"}},[c.search]);W.useEffect(()=>{go.get()?.access_token&&u(o,{replace:!0})},[u,o]),W.useEffect(()=>{const y=v=>{if(!(typeof v.data=="object"&&v.data?.type==="gsot:auth"))return;const E=v.data.payload;go.set(E),u(o,{replace:!0})};return window.addEventListener("message",y),()=>window.removeEventListener("message",y)},[u,o]);const r=async y=>{const v=await rp(y);op(v)||alert("Please allow popups to sign in.")};return I.jsx("div",{className:"flex items-center justify-center mx-auto p-4",children:I.jsxs(Xg,{className:"w-full max-w-md",children:[I.jsxs(Lg,{children:[I.jsx(Vg,{className:"text-lg md:text-xl",children:"Sign In"}),I.jsx(Zg,{className:"text-xs md:text-sm",children:"Continue with a provider below to access your account."})]}),I.jsx(Kg,{children:I.jsx("div",{className:"grid gap-4",children:I.jsx("div",{className:Tl("w-full gap-2 flex items-center","justify-between flex-col"),children:I.jsxs(lp,{variant:"outline",className:"w-full gap-2",onClick:()=>r("google"),children:[I.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"0.98em",height:"1em",viewBox:"0 0 256 262","aria-hidden":"true",focusable:"false",children:[I.jsx("path",{fill:"#4285F4",d:"M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622l38.755 30.023l2.685.268c24.659-22.774 38.875-56.282 38.875-96.027"}),I.jsx("path",{fill:"#34A853",d:"M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055c-34.523 0-63.824-22.773-74.269-54.25l-1.531.13l-40.298 31.187l-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1"}),I.jsx("path",{fill:"#FBBC05",d:"M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82c0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602z"}),I.jsx("path",{fill:"#EB4335",d:"M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0C79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251"})]}),"Sign in with Google"]})})})})]})})};function fp(){return I.jsxs(Ey,{children:[I.jsx(mh,{path:"/login",element:I.jsx(Yh,{})}),I.jsx(mh,{path:"*",element:I.jsx(Yh,{})})]})}Ny.createRoot(document.getElementById("root")).render(I.jsx(W.StrictMode,{children:I.jsx(Ty,{children:I.jsx(sg,{children:I.jsx(fp,{})})})})); +//# sourceMappingURL=index-CFwByDWI.js.map diff --git a/internal/web/dist/assets/index-CFwByDWI.js.br b/internal/web/dist/assets/index-CFwByDWI.js.br new file mode 100644 index 0000000..99e0bd5 Binary files /dev/null and b/internal/web/dist/assets/index-CFwByDWI.js.br differ diff --git a/internal/web/dist/assets/index-CFwByDWI.js.gz b/internal/web/dist/assets/index-CFwByDWI.js.gz new file mode 100644 index 0000000..4825359 Binary files /dev/null and b/internal/web/dist/assets/index-CFwByDWI.js.gz differ diff --git a/internal/web/dist/assets/index-CFwByDWI.js.map b/internal/web/dist/assets/index-CFwByDWI.js.map new file mode 100644 index 0000000..4b85f8b --- /dev/null +++ b/internal/web/dist/assets/index-CFwByDWI.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index-CFwByDWI.js","sources":["../../../../ui/node_modules/react/cjs/react-jsx-runtime.production.js","../../../../ui/node_modules/react/jsx-runtime.js","../../../../ui/node_modules/scheduler/cjs/scheduler.production.js","../../../../ui/node_modules/scheduler/index.js","../../../../ui/node_modules/react-dom/cjs/react-dom-client.production.js","../../../../ui/node_modules/react-dom/client.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/subscribable.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/timeoutManager.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/utils.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/focusManager.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/thenable.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/notifyManager.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/onlineManager.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/retryer.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/removable.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/query.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/infiniteQueryBehavior.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/mutation.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/mutationCache.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/queryCache.js","../../../../ui/node_modules/@tanstack/query-core/build/modern/queryClient.js","../../../../ui/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js","../../../../ui/node_modules/next-themes/dist/index.mjs","../../../../ui/src/providers/theme-provider.tsx","../../../../ui/node_modules/lucide-react/dist/esm/shared/src/utils.js","../../../../ui/node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../../ui/node_modules/lucide-react/dist/esm/Icon.js","../../../../ui/node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../../ui/node_modules/lucide-react/dist/esm/icons/circle-check.js","../../../../ui/node_modules/lucide-react/dist/esm/icons/info.js","../../../../ui/node_modules/lucide-react/dist/esm/icons/loader-circle.js","../../../../ui/node_modules/lucide-react/dist/esm/icons/octagon-x.js","../../../../ui/node_modules/lucide-react/dist/esm/icons/triangle-alert.js","../../../../ui/node_modules/sonner/dist/index.mjs","../../../../ui/src/components/ui/sonner.tsx","../../../../ui/src/providers/index.tsx","../../../../ui/node_modules/clsx/dist/clsx.mjs","../../../../ui/node_modules/tailwind-merge/dist/bundle-mjs.mjs","../../../../ui/src/lib/utils.ts","../../../../ui/src/components/ui/card.tsx","../../../../ui/node_modules/@radix-ui/react-compose-refs/dist/index.mjs","../../../../ui/node_modules/@radix-ui/react-slot/dist/index.mjs","../../../../ui/node_modules/class-variance-authority/dist/index.mjs","../../../../ui/src/components/ui/button.tsx","../../../../ui/src/auth/store.ts","../../../../ui/src/auth/org.ts","../../../../ui/src/sdkClient.ts","../../../../ui/src/pages/auth/login.tsx","../../../../ui/src/App.tsx","../../../../ui/src/main.tsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/**\n * @license React\n * scheduler.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nfunction push(heap, node) {\n var index = heap.length;\n heap.push(node);\n a: for (; 0 < index; ) {\n var parentIndex = (index - 1) >>> 1,\n parent = heap[parentIndex];\n if (0 < compare(parent, node))\n (heap[parentIndex] = node), (heap[index] = parent), (index = parentIndex);\n else break a;\n }\n}\nfunction peek(heap) {\n return 0 === heap.length ? null : heap[0];\n}\nfunction pop(heap) {\n if (0 === heap.length) return null;\n var first = heap[0],\n last = heap.pop();\n if (last !== first) {\n heap[0] = last;\n a: for (\n var index = 0, length = heap.length, halfLength = length >>> 1;\n index < halfLength;\n\n ) {\n var leftIndex = 2 * (index + 1) - 1,\n left = heap[leftIndex],\n rightIndex = leftIndex + 1,\n right = heap[rightIndex];\n if (0 > compare(left, last))\n rightIndex < length && 0 > compare(right, left)\n ? ((heap[index] = right),\n (heap[rightIndex] = last),\n (index = rightIndex))\n : ((heap[index] = left),\n (heap[leftIndex] = last),\n (index = leftIndex));\n else if (rightIndex < length && 0 > compare(right, last))\n (heap[index] = right), (heap[rightIndex] = last), (index = rightIndex);\n else break a;\n }\n }\n return first;\n}\nfunction compare(a, b) {\n var diff = a.sortIndex - b.sortIndex;\n return 0 !== diff ? diff : a.id - b.id;\n}\nexports.unstable_now = void 0;\nif (\"object\" === typeof performance && \"function\" === typeof performance.now) {\n var localPerformance = performance;\n exports.unstable_now = function () {\n return localPerformance.now();\n };\n} else {\n var localDate = Date,\n initialTime = localDate.now();\n exports.unstable_now = function () {\n return localDate.now() - initialTime;\n };\n}\nvar taskQueue = [],\n timerQueue = [],\n taskIdCounter = 1,\n currentTask = null,\n currentPriorityLevel = 3,\n isPerformingWork = !1,\n isHostCallbackScheduled = !1,\n isHostTimeoutScheduled = !1,\n needsPaint = !1,\n localSetTimeout = \"function\" === typeof setTimeout ? setTimeout : null,\n localClearTimeout = \"function\" === typeof clearTimeout ? clearTimeout : null,\n localSetImmediate = \"undefined\" !== typeof setImmediate ? setImmediate : null;\nfunction advanceTimers(currentTime) {\n for (var timer = peek(timerQueue); null !== timer; ) {\n if (null === timer.callback) pop(timerQueue);\n else if (timer.startTime <= currentTime)\n pop(timerQueue),\n (timer.sortIndex = timer.expirationTime),\n push(taskQueue, timer);\n else break;\n timer = peek(timerQueue);\n }\n}\nfunction handleTimeout(currentTime) {\n isHostTimeoutScheduled = !1;\n advanceTimers(currentTime);\n if (!isHostCallbackScheduled)\n if (null !== peek(taskQueue))\n (isHostCallbackScheduled = !0),\n isMessageLoopRunning ||\n ((isMessageLoopRunning = !0), schedulePerformWorkUntilDeadline());\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);\n }\n}\nvar isMessageLoopRunning = !1,\n taskTimeoutID = -1,\n frameInterval = 5,\n startTime = -1;\nfunction shouldYieldToHost() {\n return needsPaint\n ? !0\n : exports.unstable_now() - startTime < frameInterval\n ? !1\n : !0;\n}\nfunction performWorkUntilDeadline() {\n needsPaint = !1;\n if (isMessageLoopRunning) {\n var currentTime = exports.unstable_now();\n startTime = currentTime;\n var hasMoreWork = !0;\n try {\n a: {\n isHostCallbackScheduled = !1;\n isHostTimeoutScheduled &&\n ((isHostTimeoutScheduled = !1),\n localClearTimeout(taskTimeoutID),\n (taskTimeoutID = -1));\n isPerformingWork = !0;\n var previousPriorityLevel = currentPriorityLevel;\n try {\n b: {\n advanceTimers(currentTime);\n for (\n currentTask = peek(taskQueue);\n null !== currentTask &&\n !(\n currentTask.expirationTime > currentTime && shouldYieldToHost()\n );\n\n ) {\n var callback = currentTask.callback;\n if (\"function\" === typeof callback) {\n currentTask.callback = null;\n currentPriorityLevel = currentTask.priorityLevel;\n var continuationCallback = callback(\n currentTask.expirationTime <= currentTime\n );\n currentTime = exports.unstable_now();\n if (\"function\" === typeof continuationCallback) {\n currentTask.callback = continuationCallback;\n advanceTimers(currentTime);\n hasMoreWork = !0;\n break b;\n }\n currentTask === peek(taskQueue) && pop(taskQueue);\n advanceTimers(currentTime);\n } else pop(taskQueue);\n currentTask = peek(taskQueue);\n }\n if (null !== currentTask) hasMoreWork = !0;\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(\n handleTimeout,\n firstTimer.startTime - currentTime\n );\n hasMoreWork = !1;\n }\n }\n break a;\n } finally {\n (currentTask = null),\n (currentPriorityLevel = previousPriorityLevel),\n (isPerformingWork = !1);\n }\n hasMoreWork = void 0;\n }\n } finally {\n hasMoreWork\n ? schedulePerformWorkUntilDeadline()\n : (isMessageLoopRunning = !1);\n }\n }\n}\nvar schedulePerformWorkUntilDeadline;\nif (\"function\" === typeof localSetImmediate)\n schedulePerformWorkUntilDeadline = function () {\n localSetImmediate(performWorkUntilDeadline);\n };\nelse if (\"undefined\" !== typeof MessageChannel) {\n var channel = new MessageChannel(),\n port = channel.port2;\n channel.port1.onmessage = performWorkUntilDeadline;\n schedulePerformWorkUntilDeadline = function () {\n port.postMessage(null);\n };\n} else\n schedulePerformWorkUntilDeadline = function () {\n localSetTimeout(performWorkUntilDeadline, 0);\n };\nfunction requestHostTimeout(callback, ms) {\n taskTimeoutID = localSetTimeout(function () {\n callback(exports.unstable_now());\n }, ms);\n}\nexports.unstable_IdlePriority = 5;\nexports.unstable_ImmediatePriority = 1;\nexports.unstable_LowPriority = 4;\nexports.unstable_NormalPriority = 3;\nexports.unstable_Profiling = null;\nexports.unstable_UserBlockingPriority = 2;\nexports.unstable_cancelCallback = function (task) {\n task.callback = null;\n};\nexports.unstable_forceFrameRate = function (fps) {\n 0 > fps || 125 < fps\n ? console.error(\n \"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported\"\n )\n : (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 5);\n};\nexports.unstable_getCurrentPriorityLevel = function () {\n return currentPriorityLevel;\n};\nexports.unstable_next = function (eventHandler) {\n switch (currentPriorityLevel) {\n case 1:\n case 2:\n case 3:\n var priorityLevel = 3;\n break;\n default:\n priorityLevel = currentPriorityLevel;\n }\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = priorityLevel;\n try {\n return eventHandler();\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n};\nexports.unstable_requestPaint = function () {\n needsPaint = !0;\n};\nexports.unstable_runWithPriority = function (priorityLevel, eventHandler) {\n switch (priorityLevel) {\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n break;\n default:\n priorityLevel = 3;\n }\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = priorityLevel;\n try {\n return eventHandler();\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n};\nexports.unstable_scheduleCallback = function (\n priorityLevel,\n callback,\n options\n) {\n var currentTime = exports.unstable_now();\n \"object\" === typeof options && null !== options\n ? ((options = options.delay),\n (options =\n \"number\" === typeof options && 0 < options\n ? currentTime + options\n : currentTime))\n : (options = currentTime);\n switch (priorityLevel) {\n case 1:\n var timeout = -1;\n break;\n case 2:\n timeout = 250;\n break;\n case 5:\n timeout = 1073741823;\n break;\n case 4:\n timeout = 1e4;\n break;\n default:\n timeout = 5e3;\n }\n timeout = options + timeout;\n priorityLevel = {\n id: taskIdCounter++,\n callback: callback,\n priorityLevel: priorityLevel,\n startTime: options,\n expirationTime: timeout,\n sortIndex: -1\n };\n options > currentTime\n ? ((priorityLevel.sortIndex = options),\n push(timerQueue, priorityLevel),\n null === peek(taskQueue) &&\n priorityLevel === peek(timerQueue) &&\n (isHostTimeoutScheduled\n ? (localClearTimeout(taskTimeoutID), (taskTimeoutID = -1))\n : (isHostTimeoutScheduled = !0),\n requestHostTimeout(handleTimeout, options - currentTime)))\n : ((priorityLevel.sortIndex = timeout),\n push(taskQueue, priorityLevel),\n isHostCallbackScheduled ||\n isPerformingWork ||\n ((isHostCallbackScheduled = !0),\n isMessageLoopRunning ||\n ((isMessageLoopRunning = !0), schedulePerformWorkUntilDeadline())));\n return priorityLevel;\n};\nexports.unstable_shouldYield = shouldYieldToHost;\nexports.unstable_wrapCallback = function (callback) {\n var parentPriorityLevel = currentPriorityLevel;\n return function () {\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = parentPriorityLevel;\n try {\n return callback.apply(this, arguments);\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n };\n};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/scheduler.production.js');\n} else {\n module.exports = require('./cjs/scheduler.development.js');\n}\n","/**\n * @license React\n * react-dom-client.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\n\"use strict\";\nvar Scheduler = require(\"scheduler\"),\n React = require(\"react\"),\n ReactDOM = require(\"react-dom\");\nfunction formatProdErrorMessage(code) {\n var url = \"https://react.dev/errors/\" + code;\n if (1 < arguments.length) {\n url += \"?args[]=\" + encodeURIComponent(arguments[1]);\n for (var i = 2; i < arguments.length; i++)\n url += \"&args[]=\" + encodeURIComponent(arguments[i]);\n }\n return (\n \"Minified React error #\" +\n code +\n \"; visit \" +\n url +\n \" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"\n );\n}\nfunction isValidContainer(node) {\n return !(\n !node ||\n (1 !== node.nodeType && 9 !== node.nodeType && 11 !== node.nodeType)\n );\n}\nfunction getNearestMountedFiber(fiber) {\n var node = fiber,\n nearestMounted = fiber;\n if (fiber.alternate) for (; node.return; ) node = node.return;\n else {\n fiber = node;\n do\n (node = fiber),\n 0 !== (node.flags & 4098) && (nearestMounted = node.return),\n (fiber = node.return);\n while (fiber);\n }\n return 3 === node.tag ? nearestMounted : null;\n}\nfunction getSuspenseInstanceFromFiber(fiber) {\n if (13 === fiber.tag) {\n var suspenseState = fiber.memoizedState;\n null === suspenseState &&\n ((fiber = fiber.alternate),\n null !== fiber && (suspenseState = fiber.memoizedState));\n if (null !== suspenseState) return suspenseState.dehydrated;\n }\n return null;\n}\nfunction getActivityInstanceFromFiber(fiber) {\n if (31 === fiber.tag) {\n var activityState = fiber.memoizedState;\n null === activityState &&\n ((fiber = fiber.alternate),\n null !== fiber && (activityState = fiber.memoizedState));\n if (null !== activityState) return activityState.dehydrated;\n }\n return null;\n}\nfunction assertIsMounted(fiber) {\n if (getNearestMountedFiber(fiber) !== fiber)\n throw Error(formatProdErrorMessage(188));\n}\nfunction findCurrentFiberUsingSlowPath(fiber) {\n var alternate = fiber.alternate;\n if (!alternate) {\n alternate = getNearestMountedFiber(fiber);\n if (null === alternate) throw Error(formatProdErrorMessage(188));\n return alternate !== fiber ? null : fiber;\n }\n for (var a = fiber, b = alternate; ; ) {\n var parentA = a.return;\n if (null === parentA) break;\n var parentB = parentA.alternate;\n if (null === parentB) {\n b = parentA.return;\n if (null !== b) {\n a = b;\n continue;\n }\n break;\n }\n if (parentA.child === parentB.child) {\n for (parentB = parentA.child; parentB; ) {\n if (parentB === a) return assertIsMounted(parentA), fiber;\n if (parentB === b) return assertIsMounted(parentA), alternate;\n parentB = parentB.sibling;\n }\n throw Error(formatProdErrorMessage(188));\n }\n if (a.return !== b.return) (a = parentA), (b = parentB);\n else {\n for (var didFindChild = !1, child$0 = parentA.child; child$0; ) {\n if (child$0 === a) {\n didFindChild = !0;\n a = parentA;\n b = parentB;\n break;\n }\n if (child$0 === b) {\n didFindChild = !0;\n b = parentA;\n a = parentB;\n break;\n }\n child$0 = child$0.sibling;\n }\n if (!didFindChild) {\n for (child$0 = parentB.child; child$0; ) {\n if (child$0 === a) {\n didFindChild = !0;\n a = parentB;\n b = parentA;\n break;\n }\n if (child$0 === b) {\n didFindChild = !0;\n b = parentB;\n a = parentA;\n break;\n }\n child$0 = child$0.sibling;\n }\n if (!didFindChild) throw Error(formatProdErrorMessage(189));\n }\n }\n if (a.alternate !== b) throw Error(formatProdErrorMessage(190));\n }\n if (3 !== a.tag) throw Error(formatProdErrorMessage(188));\n return a.stateNode.current === a ? fiber : alternate;\n}\nfunction findCurrentHostFiberImpl(node) {\n var tag = node.tag;\n if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node;\n for (node = node.child; null !== node; ) {\n tag = findCurrentHostFiberImpl(node);\n if (null !== tag) return tag;\n node = node.sibling;\n }\n return null;\n}\nvar assign = Object.assign,\n REACT_LEGACY_ELEMENT_TYPE = Symbol.for(\"react.element\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\nSymbol.for(\"react.scope\");\nvar REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\");\nSymbol.for(\"react.legacy_hidden\");\nSymbol.for(\"react.tracing_marker\");\nvar REACT_MEMO_CACHE_SENTINEL = Symbol.for(\"react.memo_cache_sentinel\");\nSymbol.for(\"react.view_transition\");\nvar MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nfunction getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable) return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n}\nvar REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\");\nfunction getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (type.$$typeof) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n}\nvar isArrayImpl = Array.isArray,\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n ReactDOMSharedInternals =\n ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n sharedNotPendingObject = {\n pending: !1,\n data: null,\n method: null,\n action: null\n },\n valueStack = [],\n index = -1;\nfunction createCursor(defaultValue) {\n return { current: defaultValue };\n}\nfunction pop(cursor) {\n 0 > index ||\n ((cursor.current = valueStack[index]), (valueStack[index] = null), index--);\n}\nfunction push(cursor, value) {\n index++;\n valueStack[index] = cursor.current;\n cursor.current = value;\n}\nvar contextStackCursor = createCursor(null),\n contextFiberStackCursor = createCursor(null),\n rootInstanceStackCursor = createCursor(null),\n hostTransitionProviderCursor = createCursor(null);\nfunction pushHostContainer(fiber, nextRootInstance) {\n push(rootInstanceStackCursor, nextRootInstance);\n push(contextFiberStackCursor, fiber);\n push(contextStackCursor, null);\n switch (nextRootInstance.nodeType) {\n case 9:\n case 11:\n fiber = (fiber = nextRootInstance.documentElement)\n ? (fiber = fiber.namespaceURI)\n ? getOwnHostContext(fiber)\n : 0\n : 0;\n break;\n default:\n if (\n ((fiber = nextRootInstance.tagName),\n (nextRootInstance = nextRootInstance.namespaceURI))\n )\n (nextRootInstance = getOwnHostContext(nextRootInstance)),\n (fiber = getChildHostContextProd(nextRootInstance, fiber));\n else\n switch (fiber) {\n case \"svg\":\n fiber = 1;\n break;\n case \"math\":\n fiber = 2;\n break;\n default:\n fiber = 0;\n }\n }\n pop(contextStackCursor);\n push(contextStackCursor, fiber);\n}\nfunction popHostContainer() {\n pop(contextStackCursor);\n pop(contextFiberStackCursor);\n pop(rootInstanceStackCursor);\n}\nfunction pushHostContext(fiber) {\n null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber);\n var context = contextStackCursor.current;\n var JSCompiler_inline_result = getChildHostContextProd(context, fiber.type);\n context !== JSCompiler_inline_result &&\n (push(contextFiberStackCursor, fiber),\n push(contextStackCursor, JSCompiler_inline_result));\n}\nfunction popHostContext(fiber) {\n contextFiberStackCursor.current === fiber &&\n (pop(contextStackCursor), pop(contextFiberStackCursor));\n hostTransitionProviderCursor.current === fiber &&\n (pop(hostTransitionProviderCursor),\n (HostTransitionContext._currentValue = sharedNotPendingObject));\n}\nvar prefix, suffix;\nfunction describeBuiltInComponentFrame(name) {\n if (void 0 === prefix)\n try {\n throw Error();\n } catch (x) {\n var match = x.stack.trim().match(/\\n( *(at )?)/);\n prefix = (match && match[1]) || \"\";\n suffix =\n -1 < x.stack.indexOf(\"\\n at\")\n ? \" ()\"\n : -1 < x.stack.indexOf(\"@\")\n ? \"@unknown:0:0\"\n : \"\";\n }\n return \"\\n\" + prefix + name + suffix;\n}\nvar reentry = !1;\nfunction describeNativeComponentFrame(fn, construct) {\n if (!fn || reentry) return \"\";\n reentry = !0;\n var previousPrepareStackTrace = Error.prepareStackTrace;\n Error.prepareStackTrace = void 0;\n try {\n var RunInRootFrame = {\n DetermineComponentFrameRoot: function () {\n try {\n if (construct) {\n var Fake = function () {\n throw Error();\n };\n Object.defineProperty(Fake.prototype, \"props\", {\n set: function () {\n throw Error();\n }\n });\n if (\"object\" === typeof Reflect && Reflect.construct) {\n try {\n Reflect.construct(Fake, []);\n } catch (x) {\n var control = x;\n }\n Reflect.construct(fn, [], Fake);\n } else {\n try {\n Fake.call();\n } catch (x$1) {\n control = x$1;\n }\n fn.call(Fake.prototype);\n }\n } else {\n try {\n throw Error();\n } catch (x$2) {\n control = x$2;\n }\n (Fake = fn()) &&\n \"function\" === typeof Fake.catch &&\n Fake.catch(function () {});\n }\n } catch (sample) {\n if (sample && control && \"string\" === typeof sample.stack)\n return [sample.stack, control.stack];\n }\n return [null, null];\n }\n };\n RunInRootFrame.DetermineComponentFrameRoot.displayName =\n \"DetermineComponentFrameRoot\";\n var namePropDescriptor = Object.getOwnPropertyDescriptor(\n RunInRootFrame.DetermineComponentFrameRoot,\n \"name\"\n );\n namePropDescriptor &&\n namePropDescriptor.configurable &&\n Object.defineProperty(\n RunInRootFrame.DetermineComponentFrameRoot,\n \"name\",\n { value: \"DetermineComponentFrameRoot\" }\n );\n var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(),\n sampleStack = _RunInRootFrame$Deter[0],\n controlStack = _RunInRootFrame$Deter[1];\n if (sampleStack && controlStack) {\n var sampleLines = sampleStack.split(\"\\n\"),\n controlLines = controlStack.split(\"\\n\");\n for (\n namePropDescriptor = RunInRootFrame = 0;\n RunInRootFrame < sampleLines.length &&\n !sampleLines[RunInRootFrame].includes(\"DetermineComponentFrameRoot\");\n\n )\n RunInRootFrame++;\n for (\n ;\n namePropDescriptor < controlLines.length &&\n !controlLines[namePropDescriptor].includes(\n \"DetermineComponentFrameRoot\"\n );\n\n )\n namePropDescriptor++;\n if (\n RunInRootFrame === sampleLines.length ||\n namePropDescriptor === controlLines.length\n )\n for (\n RunInRootFrame = sampleLines.length - 1,\n namePropDescriptor = controlLines.length - 1;\n 1 <= RunInRootFrame &&\n 0 <= namePropDescriptor &&\n sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor];\n\n )\n namePropDescriptor--;\n for (\n ;\n 1 <= RunInRootFrame && 0 <= namePropDescriptor;\n RunInRootFrame--, namePropDescriptor--\n )\n if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) {\n if (1 !== RunInRootFrame || 1 !== namePropDescriptor) {\n do\n if (\n (RunInRootFrame--,\n namePropDescriptor--,\n 0 > namePropDescriptor ||\n sampleLines[RunInRootFrame] !==\n controlLines[namePropDescriptor])\n ) {\n var frame =\n \"\\n\" +\n sampleLines[RunInRootFrame].replace(\" at new \", \" at \");\n fn.displayName &&\n frame.includes(\"\") &&\n (frame = frame.replace(\"\", fn.displayName));\n return frame;\n }\n while (1 <= RunInRootFrame && 0 <= namePropDescriptor);\n }\n break;\n }\n }\n } finally {\n (reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace);\n }\n return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : \"\")\n ? describeBuiltInComponentFrame(previousPrepareStackTrace)\n : \"\";\n}\nfunction describeFiber(fiber, childFiber) {\n switch (fiber.tag) {\n case 26:\n case 27:\n case 5:\n return describeBuiltInComponentFrame(fiber.type);\n case 16:\n return describeBuiltInComponentFrame(\"Lazy\");\n case 13:\n return fiber.child !== childFiber && null !== childFiber\n ? describeBuiltInComponentFrame(\"Suspense Fallback\")\n : describeBuiltInComponentFrame(\"Suspense\");\n case 19:\n return describeBuiltInComponentFrame(\"SuspenseList\");\n case 0:\n case 15:\n return describeNativeComponentFrame(fiber.type, !1);\n case 11:\n return describeNativeComponentFrame(fiber.type.render, !1);\n case 1:\n return describeNativeComponentFrame(fiber.type, !0);\n case 31:\n return describeBuiltInComponentFrame(\"Activity\");\n default:\n return \"\";\n }\n}\nfunction getStackByFiberInDevAndProd(workInProgress) {\n try {\n var info = \"\",\n previous = null;\n do\n (info += describeFiber(workInProgress, previous)),\n (previous = workInProgress),\n (workInProgress = workInProgress.return);\n while (workInProgress);\n return info;\n } catch (x) {\n return \"\\nError generating stack: \" + x.message + \"\\n\" + x.stack;\n }\n}\nvar hasOwnProperty = Object.prototype.hasOwnProperty,\n scheduleCallback$3 = Scheduler.unstable_scheduleCallback,\n cancelCallback$1 = Scheduler.unstable_cancelCallback,\n shouldYield = Scheduler.unstable_shouldYield,\n requestPaint = Scheduler.unstable_requestPaint,\n now = Scheduler.unstable_now,\n getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,\n ImmediatePriority = Scheduler.unstable_ImmediatePriority,\n UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,\n NormalPriority$1 = Scheduler.unstable_NormalPriority,\n LowPriority = Scheduler.unstable_LowPriority,\n IdlePriority = Scheduler.unstable_IdlePriority,\n log$1 = Scheduler.log,\n unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue,\n rendererID = null,\n injectedHook = null;\nfunction setIsStrictModeForDevtools(newIsStrictMode) {\n \"function\" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode);\n if (injectedHook && \"function\" === typeof injectedHook.setStrictMode)\n try {\n injectedHook.setStrictMode(rendererID, newIsStrictMode);\n } catch (err) {}\n}\nvar clz32 = Math.clz32 ? Math.clz32 : clz32Fallback,\n log = Math.log,\n LN2 = Math.LN2;\nfunction clz32Fallback(x) {\n x >>>= 0;\n return 0 === x ? 32 : (31 - ((log(x) / LN2) | 0)) | 0;\n}\nvar nextTransitionUpdateLane = 256,\n nextTransitionDeferredLane = 262144,\n nextRetryLane = 4194304;\nfunction getHighestPriorityLanes(lanes) {\n var pendingSyncLanes = lanes & 42;\n if (0 !== pendingSyncLanes) return pendingSyncLanes;\n switch (lanes & -lanes) {\n case 1:\n return 1;\n case 2:\n return 2;\n case 4:\n return 4;\n case 8:\n return 8;\n case 16:\n return 16;\n case 32:\n return 32;\n case 64:\n return 64;\n case 128:\n return 128;\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n return lanes & 261888;\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n return lanes & 3932160;\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n return lanes & 62914560;\n case 67108864:\n return 67108864;\n case 134217728:\n return 134217728;\n case 268435456:\n return 268435456;\n case 536870912:\n return 536870912;\n case 1073741824:\n return 0;\n default:\n return lanes;\n }\n}\nfunction getNextLanes(root, wipLanes, rootHasPendingCommit) {\n var pendingLanes = root.pendingLanes;\n if (0 === pendingLanes) return 0;\n var nextLanes = 0,\n suspendedLanes = root.suspendedLanes,\n pingedLanes = root.pingedLanes;\n root = root.warmLanes;\n var nonIdlePendingLanes = pendingLanes & 134217727;\n 0 !== nonIdlePendingLanes\n ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes),\n 0 !== pendingLanes\n ? (nextLanes = getHighestPriorityLanes(pendingLanes))\n : ((pingedLanes &= nonIdlePendingLanes),\n 0 !== pingedLanes\n ? (nextLanes = getHighestPriorityLanes(pingedLanes))\n : rootHasPendingCommit ||\n ((rootHasPendingCommit = nonIdlePendingLanes & ~root),\n 0 !== rootHasPendingCommit &&\n (nextLanes = getHighestPriorityLanes(rootHasPendingCommit)))))\n : ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes),\n 0 !== nonIdlePendingLanes\n ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes))\n : 0 !== pingedLanes\n ? (nextLanes = getHighestPriorityLanes(pingedLanes))\n : rootHasPendingCommit ||\n ((rootHasPendingCommit = pendingLanes & ~root),\n 0 !== rootHasPendingCommit &&\n (nextLanes = getHighestPriorityLanes(rootHasPendingCommit))));\n return 0 === nextLanes\n ? 0\n : 0 !== wipLanes &&\n wipLanes !== nextLanes &&\n 0 === (wipLanes & suspendedLanes) &&\n ((suspendedLanes = nextLanes & -nextLanes),\n (rootHasPendingCommit = wipLanes & -wipLanes),\n suspendedLanes >= rootHasPendingCommit ||\n (32 === suspendedLanes && 0 !== (rootHasPendingCommit & 4194048)))\n ? wipLanes\n : nextLanes;\n}\nfunction checkIfRootIsPrerendering(root, renderLanes) {\n return (\n 0 ===\n (root.pendingLanes &\n ~(root.suspendedLanes & ~root.pingedLanes) &\n renderLanes)\n );\n}\nfunction computeExpirationTime(lane, currentTime) {\n switch (lane) {\n case 1:\n case 2:\n case 4:\n case 8:\n case 64:\n return currentTime + 250;\n case 16:\n case 32:\n case 128:\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n return currentTime + 5e3;\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n return -1;\n case 67108864:\n case 134217728:\n case 268435456:\n case 536870912:\n case 1073741824:\n return -1;\n default:\n return -1;\n }\n}\nfunction claimNextRetryLane() {\n var lane = nextRetryLane;\n nextRetryLane <<= 1;\n 0 === (nextRetryLane & 62914560) && (nextRetryLane = 4194304);\n return lane;\n}\nfunction createLaneMap(initial) {\n for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial);\n return laneMap;\n}\nfunction markRootUpdated$1(root, updateLane) {\n root.pendingLanes |= updateLane;\n 268435456 !== updateLane &&\n ((root.suspendedLanes = 0), (root.pingedLanes = 0), (root.warmLanes = 0));\n}\nfunction markRootFinished(\n root,\n finishedLanes,\n remainingLanes,\n spawnedLane,\n updatedLanes,\n suspendedRetryLanes\n) {\n var previouslyPendingLanes = root.pendingLanes;\n root.pendingLanes = remainingLanes;\n root.suspendedLanes = 0;\n root.pingedLanes = 0;\n root.warmLanes = 0;\n root.expiredLanes &= remainingLanes;\n root.entangledLanes &= remainingLanes;\n root.errorRecoveryDisabledLanes &= remainingLanes;\n root.shellSuspendCounter = 0;\n var entanglements = root.entanglements,\n expirationTimes = root.expirationTimes,\n hiddenUpdates = root.hiddenUpdates;\n for (\n remainingLanes = previouslyPendingLanes & ~remainingLanes;\n 0 < remainingLanes;\n\n ) {\n var index$7 = 31 - clz32(remainingLanes),\n lane = 1 << index$7;\n entanglements[index$7] = 0;\n expirationTimes[index$7] = -1;\n var hiddenUpdatesForLane = hiddenUpdates[index$7];\n if (null !== hiddenUpdatesForLane)\n for (\n hiddenUpdates[index$7] = null, index$7 = 0;\n index$7 < hiddenUpdatesForLane.length;\n index$7++\n ) {\n var update = hiddenUpdatesForLane[index$7];\n null !== update && (update.lane &= -536870913);\n }\n remainingLanes &= ~lane;\n }\n 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, 0);\n 0 !== suspendedRetryLanes &&\n 0 === updatedLanes &&\n 0 !== root.tag &&\n (root.suspendedLanes |=\n suspendedRetryLanes & ~(previouslyPendingLanes & ~finishedLanes));\n}\nfunction markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {\n root.pendingLanes |= spawnedLane;\n root.suspendedLanes &= ~spawnedLane;\n var spawnedLaneIndex = 31 - clz32(spawnedLane);\n root.entangledLanes |= spawnedLane;\n root.entanglements[spawnedLaneIndex] =\n root.entanglements[spawnedLaneIndex] |\n 1073741824 |\n (entangledLanes & 261930);\n}\nfunction markRootEntangled(root, entangledLanes) {\n var rootEntangledLanes = (root.entangledLanes |= entangledLanes);\n for (root = root.entanglements; rootEntangledLanes; ) {\n var index$8 = 31 - clz32(rootEntangledLanes),\n lane = 1 << index$8;\n (lane & entangledLanes) | (root[index$8] & entangledLanes) &&\n (root[index$8] |= entangledLanes);\n rootEntangledLanes &= ~lane;\n }\n}\nfunction getBumpedLaneForHydration(root, renderLanes) {\n var renderLane = renderLanes & -renderLanes;\n renderLane =\n 0 !== (renderLane & 42) ? 1 : getBumpedLaneForHydrationByLane(renderLane);\n return 0 !== (renderLane & (root.suspendedLanes | renderLanes))\n ? 0\n : renderLane;\n}\nfunction getBumpedLaneForHydrationByLane(lane) {\n switch (lane) {\n case 2:\n lane = 1;\n break;\n case 8:\n lane = 4;\n break;\n case 32:\n lane = 16;\n break;\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n lane = 128;\n break;\n case 268435456:\n lane = 134217728;\n break;\n default:\n lane = 0;\n }\n return lane;\n}\nfunction lanesToEventPriority(lanes) {\n lanes &= -lanes;\n return 2 < lanes\n ? 8 < lanes\n ? 0 !== (lanes & 134217727)\n ? 32\n : 268435456\n : 8\n : 2;\n}\nfunction resolveUpdatePriority() {\n var updatePriority = ReactDOMSharedInternals.p;\n if (0 !== updatePriority) return updatePriority;\n updatePriority = window.event;\n return void 0 === updatePriority ? 32 : getEventPriority(updatePriority.type);\n}\nfunction runWithPriority(priority, fn) {\n var previousPriority = ReactDOMSharedInternals.p;\n try {\n return (ReactDOMSharedInternals.p = priority), fn();\n } finally {\n ReactDOMSharedInternals.p = previousPriority;\n }\n}\nvar randomKey = Math.random().toString(36).slice(2),\n internalInstanceKey = \"__reactFiber$\" + randomKey,\n internalPropsKey = \"__reactProps$\" + randomKey,\n internalContainerInstanceKey = \"__reactContainer$\" + randomKey,\n internalEventHandlersKey = \"__reactEvents$\" + randomKey,\n internalEventHandlerListenersKey = \"__reactListeners$\" + randomKey,\n internalEventHandlesSetKey = \"__reactHandles$\" + randomKey,\n internalRootNodeResourcesKey = \"__reactResources$\" + randomKey,\n internalHoistableMarker = \"__reactMarker$\" + randomKey;\nfunction detachDeletedInstance(node) {\n delete node[internalInstanceKey];\n delete node[internalPropsKey];\n delete node[internalEventHandlersKey];\n delete node[internalEventHandlerListenersKey];\n delete node[internalEventHandlesSetKey];\n}\nfunction getClosestInstanceFromNode(targetNode) {\n var targetInst = targetNode[internalInstanceKey];\n if (targetInst) return targetInst;\n for (var parentNode = targetNode.parentNode; parentNode; ) {\n if (\n (targetInst =\n parentNode[internalContainerInstanceKey] ||\n parentNode[internalInstanceKey])\n ) {\n parentNode = targetInst.alternate;\n if (\n null !== targetInst.child ||\n (null !== parentNode && null !== parentNode.child)\n )\n for (\n targetNode = getParentHydrationBoundary(targetNode);\n null !== targetNode;\n\n ) {\n if ((parentNode = targetNode[internalInstanceKey])) return parentNode;\n targetNode = getParentHydrationBoundary(targetNode);\n }\n return targetInst;\n }\n targetNode = parentNode;\n parentNode = targetNode.parentNode;\n }\n return null;\n}\nfunction getInstanceFromNode(node) {\n if (\n (node = node[internalInstanceKey] || node[internalContainerInstanceKey])\n ) {\n var tag = node.tag;\n if (\n 5 === tag ||\n 6 === tag ||\n 13 === tag ||\n 31 === tag ||\n 26 === tag ||\n 27 === tag ||\n 3 === tag\n )\n return node;\n }\n return null;\n}\nfunction getNodeFromInstance(inst) {\n var tag = inst.tag;\n if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return inst.stateNode;\n throw Error(formatProdErrorMessage(33));\n}\nfunction getResourcesFromRoot(root) {\n var resources = root[internalRootNodeResourcesKey];\n resources ||\n (resources = root[internalRootNodeResourcesKey] =\n { hoistableStyles: new Map(), hoistableScripts: new Map() });\n return resources;\n}\nfunction markNodeAsHoistable(node) {\n node[internalHoistableMarker] = !0;\n}\nvar allNativeEvents = new Set(),\n registrationNameDependencies = {};\nfunction registerTwoPhaseEvent(registrationName, dependencies) {\n registerDirectEvent(registrationName, dependencies);\n registerDirectEvent(registrationName + \"Capture\", dependencies);\n}\nfunction registerDirectEvent(registrationName, dependencies) {\n registrationNameDependencies[registrationName] = dependencies;\n for (\n registrationName = 0;\n registrationName < dependencies.length;\n registrationName++\n )\n allNativeEvents.add(dependencies[registrationName]);\n}\nvar VALID_ATTRIBUTE_NAME_REGEX = RegExp(\n \"^[:A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD][:A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD\\\\-.0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040]*$\"\n ),\n illegalAttributeNameCache = {},\n validatedAttributeNameCache = {};\nfunction isAttributeNameSafe(attributeName) {\n if (hasOwnProperty.call(validatedAttributeNameCache, attributeName))\n return !0;\n if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) return !1;\n if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName))\n return (validatedAttributeNameCache[attributeName] = !0);\n illegalAttributeNameCache[attributeName] = !0;\n return !1;\n}\nfunction setValueForAttribute(node, name, value) {\n if (isAttributeNameSafe(name))\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n node.removeAttribute(name);\n return;\n case \"boolean\":\n var prefix$10 = name.toLowerCase().slice(0, 5);\n if (\"data-\" !== prefix$10 && \"aria-\" !== prefix$10) {\n node.removeAttribute(name);\n return;\n }\n }\n node.setAttribute(name, \"\" + value);\n }\n}\nfunction setValueForKnownAttribute(node, name, value) {\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n case \"boolean\":\n node.removeAttribute(name);\n return;\n }\n node.setAttribute(name, \"\" + value);\n }\n}\nfunction setValueForNamespacedAttribute(node, namespace, name, value) {\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n case \"boolean\":\n node.removeAttribute(name);\n return;\n }\n node.setAttributeNS(namespace, name, \"\" + value);\n }\n}\nfunction getToStringValue(value) {\n switch (typeof value) {\n case \"bigint\":\n case \"boolean\":\n case \"number\":\n case \"string\":\n case \"undefined\":\n return value;\n case \"object\":\n return value;\n default:\n return \"\";\n }\n}\nfunction isCheckable(elem) {\n var type = elem.type;\n return (\n (elem = elem.nodeName) &&\n \"input\" === elem.toLowerCase() &&\n (\"checkbox\" === type || \"radio\" === type)\n );\n}\nfunction trackValueOnNode(node, valueField, currentValue) {\n var descriptor = Object.getOwnPropertyDescriptor(\n node.constructor.prototype,\n valueField\n );\n if (\n !node.hasOwnProperty(valueField) &&\n \"undefined\" !== typeof descriptor &&\n \"function\" === typeof descriptor.get &&\n \"function\" === typeof descriptor.set\n ) {\n var get = descriptor.get,\n set = descriptor.set;\n Object.defineProperty(node, valueField, {\n configurable: !0,\n get: function () {\n return get.call(this);\n },\n set: function (value) {\n currentValue = \"\" + value;\n set.call(this, value);\n }\n });\n Object.defineProperty(node, valueField, {\n enumerable: descriptor.enumerable\n });\n return {\n getValue: function () {\n return currentValue;\n },\n setValue: function (value) {\n currentValue = \"\" + value;\n },\n stopTracking: function () {\n node._valueTracker = null;\n delete node[valueField];\n }\n };\n }\n}\nfunction track(node) {\n if (!node._valueTracker) {\n var valueField = isCheckable(node) ? \"checked\" : \"value\";\n node._valueTracker = trackValueOnNode(\n node,\n valueField,\n \"\" + node[valueField]\n );\n }\n}\nfunction updateValueIfChanged(node) {\n if (!node) return !1;\n var tracker = node._valueTracker;\n if (!tracker) return !0;\n var lastValue = tracker.getValue();\n var value = \"\";\n node &&\n (value = isCheckable(node)\n ? node.checked\n ? \"true\"\n : \"false\"\n : node.value);\n node = value;\n return node !== lastValue ? (tracker.setValue(node), !0) : !1;\n}\nfunction getActiveElement(doc) {\n doc = doc || (\"undefined\" !== typeof document ? document : void 0);\n if (\"undefined\" === typeof doc) return null;\n try {\n return doc.activeElement || doc.body;\n } catch (e) {\n return doc.body;\n }\n}\nvar escapeSelectorAttributeValueInsideDoubleQuotesRegex = /[\\n\"\\\\]/g;\nfunction escapeSelectorAttributeValueInsideDoubleQuotes(value) {\n return value.replace(\n escapeSelectorAttributeValueInsideDoubleQuotesRegex,\n function (ch) {\n return \"\\\\\" + ch.charCodeAt(0).toString(16) + \" \";\n }\n );\n}\nfunction updateInput(\n element,\n value,\n defaultValue,\n lastDefaultValue,\n checked,\n defaultChecked,\n type,\n name\n) {\n element.name = \"\";\n null != type &&\n \"function\" !== typeof type &&\n \"symbol\" !== typeof type &&\n \"boolean\" !== typeof type\n ? (element.type = type)\n : element.removeAttribute(\"type\");\n if (null != value)\n if (\"number\" === type) {\n if ((0 === value && \"\" === element.value) || element.value != value)\n element.value = \"\" + getToStringValue(value);\n } else\n element.value !== \"\" + getToStringValue(value) &&\n (element.value = \"\" + getToStringValue(value));\n else\n (\"submit\" !== type && \"reset\" !== type) || element.removeAttribute(\"value\");\n null != value\n ? setDefaultValue(element, type, getToStringValue(value))\n : null != defaultValue\n ? setDefaultValue(element, type, getToStringValue(defaultValue))\n : null != lastDefaultValue && element.removeAttribute(\"value\");\n null == checked &&\n null != defaultChecked &&\n (element.defaultChecked = !!defaultChecked);\n null != checked &&\n (element.checked =\n checked && \"function\" !== typeof checked && \"symbol\" !== typeof checked);\n null != name &&\n \"function\" !== typeof name &&\n \"symbol\" !== typeof name &&\n \"boolean\" !== typeof name\n ? (element.name = \"\" + getToStringValue(name))\n : element.removeAttribute(\"name\");\n}\nfunction initInput(\n element,\n value,\n defaultValue,\n checked,\n defaultChecked,\n type,\n name,\n isHydrating\n) {\n null != type &&\n \"function\" !== typeof type &&\n \"symbol\" !== typeof type &&\n \"boolean\" !== typeof type &&\n (element.type = type);\n if (null != value || null != defaultValue) {\n if (\n !(\n (\"submit\" !== type && \"reset\" !== type) ||\n (void 0 !== value && null !== value)\n )\n ) {\n track(element);\n return;\n }\n defaultValue =\n null != defaultValue ? \"\" + getToStringValue(defaultValue) : \"\";\n value = null != value ? \"\" + getToStringValue(value) : defaultValue;\n isHydrating || value === element.value || (element.value = value);\n element.defaultValue = value;\n }\n checked = null != checked ? checked : defaultChecked;\n checked =\n \"function\" !== typeof checked && \"symbol\" !== typeof checked && !!checked;\n element.checked = isHydrating ? element.checked : !!checked;\n element.defaultChecked = !!checked;\n null != name &&\n \"function\" !== typeof name &&\n \"symbol\" !== typeof name &&\n \"boolean\" !== typeof name &&\n (element.name = name);\n track(element);\n}\nfunction setDefaultValue(node, type, value) {\n (\"number\" === type && getActiveElement(node.ownerDocument) === node) ||\n node.defaultValue === \"\" + value ||\n (node.defaultValue = \"\" + value);\n}\nfunction updateOptions(node, multiple, propValue, setDefaultSelected) {\n node = node.options;\n if (multiple) {\n multiple = {};\n for (var i = 0; i < propValue.length; i++)\n multiple[\"$\" + propValue[i]] = !0;\n for (propValue = 0; propValue < node.length; propValue++)\n (i = multiple.hasOwnProperty(\"$\" + node[propValue].value)),\n node[propValue].selected !== i && (node[propValue].selected = i),\n i && setDefaultSelected && (node[propValue].defaultSelected = !0);\n } else {\n propValue = \"\" + getToStringValue(propValue);\n multiple = null;\n for (i = 0; i < node.length; i++) {\n if (node[i].value === propValue) {\n node[i].selected = !0;\n setDefaultSelected && (node[i].defaultSelected = !0);\n return;\n }\n null !== multiple || node[i].disabled || (multiple = node[i]);\n }\n null !== multiple && (multiple.selected = !0);\n }\n}\nfunction updateTextarea(element, value, defaultValue) {\n if (\n null != value &&\n ((value = \"\" + getToStringValue(value)),\n value !== element.value && (element.value = value),\n null == defaultValue)\n ) {\n element.defaultValue !== value && (element.defaultValue = value);\n return;\n }\n element.defaultValue =\n null != defaultValue ? \"\" + getToStringValue(defaultValue) : \"\";\n}\nfunction initTextarea(element, value, defaultValue, children) {\n if (null == value) {\n if (null != children) {\n if (null != defaultValue) throw Error(formatProdErrorMessage(92));\n if (isArrayImpl(children)) {\n if (1 < children.length) throw Error(formatProdErrorMessage(93));\n children = children[0];\n }\n defaultValue = children;\n }\n null == defaultValue && (defaultValue = \"\");\n value = defaultValue;\n }\n defaultValue = getToStringValue(value);\n element.defaultValue = defaultValue;\n children = element.textContent;\n children === defaultValue &&\n \"\" !== children &&\n null !== children &&\n (element.value = children);\n track(element);\n}\nfunction setTextContent(node, text) {\n if (text) {\n var firstChild = node.firstChild;\n if (\n firstChild &&\n firstChild === node.lastChild &&\n 3 === firstChild.nodeType\n ) {\n firstChild.nodeValue = text;\n return;\n }\n }\n node.textContent = text;\n}\nvar unitlessNumbers = new Set(\n \"animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp\".split(\n \" \"\n )\n);\nfunction setValueForStyle(style, styleName, value) {\n var isCustomProperty = 0 === styleName.indexOf(\"--\");\n null == value || \"boolean\" === typeof value || \"\" === value\n ? isCustomProperty\n ? style.setProperty(styleName, \"\")\n : \"float\" === styleName\n ? (style.cssFloat = \"\")\n : (style[styleName] = \"\")\n : isCustomProperty\n ? style.setProperty(styleName, value)\n : \"number\" !== typeof value ||\n 0 === value ||\n unitlessNumbers.has(styleName)\n ? \"float\" === styleName\n ? (style.cssFloat = value)\n : (style[styleName] = (\"\" + value).trim())\n : (style[styleName] = value + \"px\");\n}\nfunction setValueForStyles(node, styles, prevStyles) {\n if (null != styles && \"object\" !== typeof styles)\n throw Error(formatProdErrorMessage(62));\n node = node.style;\n if (null != prevStyles) {\n for (var styleName in prevStyles)\n !prevStyles.hasOwnProperty(styleName) ||\n (null != styles && styles.hasOwnProperty(styleName)) ||\n (0 === styleName.indexOf(\"--\")\n ? node.setProperty(styleName, \"\")\n : \"float\" === styleName\n ? (node.cssFloat = \"\")\n : (node[styleName] = \"\"));\n for (var styleName$16 in styles)\n (styleName = styles[styleName$16]),\n styles.hasOwnProperty(styleName$16) &&\n prevStyles[styleName$16] !== styleName &&\n setValueForStyle(node, styleName$16, styleName);\n } else\n for (var styleName$17 in styles)\n styles.hasOwnProperty(styleName$17) &&\n setValueForStyle(node, styleName$17, styles[styleName$17]);\n}\nfunction isCustomElement(tagName) {\n if (-1 === tagName.indexOf(\"-\")) return !1;\n switch (tagName) {\n case \"annotation-xml\":\n case \"color-profile\":\n case \"font-face\":\n case \"font-face-src\":\n case \"font-face-uri\":\n case \"font-face-format\":\n case \"font-face-name\":\n case \"missing-glyph\":\n return !1;\n default:\n return !0;\n }\n}\nvar aliases = new Map([\n [\"acceptCharset\", \"accept-charset\"],\n [\"htmlFor\", \"for\"],\n [\"httpEquiv\", \"http-equiv\"],\n [\"crossOrigin\", \"crossorigin\"],\n [\"accentHeight\", \"accent-height\"],\n [\"alignmentBaseline\", \"alignment-baseline\"],\n [\"arabicForm\", \"arabic-form\"],\n [\"baselineShift\", \"baseline-shift\"],\n [\"capHeight\", \"cap-height\"],\n [\"clipPath\", \"clip-path\"],\n [\"clipRule\", \"clip-rule\"],\n [\"colorInterpolation\", \"color-interpolation\"],\n [\"colorInterpolationFilters\", \"color-interpolation-filters\"],\n [\"colorProfile\", \"color-profile\"],\n [\"colorRendering\", \"color-rendering\"],\n [\"dominantBaseline\", \"dominant-baseline\"],\n [\"enableBackground\", \"enable-background\"],\n [\"fillOpacity\", \"fill-opacity\"],\n [\"fillRule\", \"fill-rule\"],\n [\"floodColor\", \"flood-color\"],\n [\"floodOpacity\", \"flood-opacity\"],\n [\"fontFamily\", \"font-family\"],\n [\"fontSize\", \"font-size\"],\n [\"fontSizeAdjust\", \"font-size-adjust\"],\n [\"fontStretch\", \"font-stretch\"],\n [\"fontStyle\", \"font-style\"],\n [\"fontVariant\", \"font-variant\"],\n [\"fontWeight\", \"font-weight\"],\n [\"glyphName\", \"glyph-name\"],\n [\"glyphOrientationHorizontal\", \"glyph-orientation-horizontal\"],\n [\"glyphOrientationVertical\", \"glyph-orientation-vertical\"],\n [\"horizAdvX\", \"horiz-adv-x\"],\n [\"horizOriginX\", \"horiz-origin-x\"],\n [\"imageRendering\", \"image-rendering\"],\n [\"letterSpacing\", \"letter-spacing\"],\n [\"lightingColor\", \"lighting-color\"],\n [\"markerEnd\", \"marker-end\"],\n [\"markerMid\", \"marker-mid\"],\n [\"markerStart\", \"marker-start\"],\n [\"overlinePosition\", \"overline-position\"],\n [\"overlineThickness\", \"overline-thickness\"],\n [\"paintOrder\", \"paint-order\"],\n [\"panose-1\", \"panose-1\"],\n [\"pointerEvents\", \"pointer-events\"],\n [\"renderingIntent\", \"rendering-intent\"],\n [\"shapeRendering\", \"shape-rendering\"],\n [\"stopColor\", \"stop-color\"],\n [\"stopOpacity\", \"stop-opacity\"],\n [\"strikethroughPosition\", \"strikethrough-position\"],\n [\"strikethroughThickness\", \"strikethrough-thickness\"],\n [\"strokeDasharray\", \"stroke-dasharray\"],\n [\"strokeDashoffset\", \"stroke-dashoffset\"],\n [\"strokeLinecap\", \"stroke-linecap\"],\n [\"strokeLinejoin\", \"stroke-linejoin\"],\n [\"strokeMiterlimit\", \"stroke-miterlimit\"],\n [\"strokeOpacity\", \"stroke-opacity\"],\n [\"strokeWidth\", \"stroke-width\"],\n [\"textAnchor\", \"text-anchor\"],\n [\"textDecoration\", \"text-decoration\"],\n [\"textRendering\", \"text-rendering\"],\n [\"transformOrigin\", \"transform-origin\"],\n [\"underlinePosition\", \"underline-position\"],\n [\"underlineThickness\", \"underline-thickness\"],\n [\"unicodeBidi\", \"unicode-bidi\"],\n [\"unicodeRange\", \"unicode-range\"],\n [\"unitsPerEm\", \"units-per-em\"],\n [\"vAlphabetic\", \"v-alphabetic\"],\n [\"vHanging\", \"v-hanging\"],\n [\"vIdeographic\", \"v-ideographic\"],\n [\"vMathematical\", \"v-mathematical\"],\n [\"vectorEffect\", \"vector-effect\"],\n [\"vertAdvY\", \"vert-adv-y\"],\n [\"vertOriginX\", \"vert-origin-x\"],\n [\"vertOriginY\", \"vert-origin-y\"],\n [\"wordSpacing\", \"word-spacing\"],\n [\"writingMode\", \"writing-mode\"],\n [\"xmlnsXlink\", \"xmlns:xlink\"],\n [\"xHeight\", \"x-height\"]\n ]),\n isJavaScriptProtocol =\n /^[\\u0000-\\u001F ]*j[\\r\\n\\t]*a[\\r\\n\\t]*v[\\r\\n\\t]*a[\\r\\n\\t]*s[\\r\\n\\t]*c[\\r\\n\\t]*r[\\r\\n\\t]*i[\\r\\n\\t]*p[\\r\\n\\t]*t[\\r\\n\\t]*:/i;\nfunction sanitizeURL(url) {\n return isJavaScriptProtocol.test(\"\" + url)\n ? \"javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')\"\n : url;\n}\nfunction noop$1() {}\nvar currentReplayingEvent = null;\nfunction getEventTarget(nativeEvent) {\n nativeEvent = nativeEvent.target || nativeEvent.srcElement || window;\n nativeEvent.correspondingUseElement &&\n (nativeEvent = nativeEvent.correspondingUseElement);\n return 3 === nativeEvent.nodeType ? nativeEvent.parentNode : nativeEvent;\n}\nvar restoreTarget = null,\n restoreQueue = null;\nfunction restoreStateOfTarget(target) {\n var internalInstance = getInstanceFromNode(target);\n if (internalInstance && (target = internalInstance.stateNode)) {\n var props = target[internalPropsKey] || null;\n a: switch (((target = internalInstance.stateNode), internalInstance.type)) {\n case \"input\":\n updateInput(\n target,\n props.value,\n props.defaultValue,\n props.defaultValue,\n props.checked,\n props.defaultChecked,\n props.type,\n props.name\n );\n internalInstance = props.name;\n if (\"radio\" === props.type && null != internalInstance) {\n for (props = target; props.parentNode; ) props = props.parentNode;\n props = props.querySelectorAll(\n 'input[name=\"' +\n escapeSelectorAttributeValueInsideDoubleQuotes(\n \"\" + internalInstance\n ) +\n '\"][type=\"radio\"]'\n );\n for (\n internalInstance = 0;\n internalInstance < props.length;\n internalInstance++\n ) {\n var otherNode = props[internalInstance];\n if (otherNode !== target && otherNode.form === target.form) {\n var otherProps = otherNode[internalPropsKey] || null;\n if (!otherProps) throw Error(formatProdErrorMessage(90));\n updateInput(\n otherNode,\n otherProps.value,\n otherProps.defaultValue,\n otherProps.defaultValue,\n otherProps.checked,\n otherProps.defaultChecked,\n otherProps.type,\n otherProps.name\n );\n }\n }\n for (\n internalInstance = 0;\n internalInstance < props.length;\n internalInstance++\n )\n (otherNode = props[internalInstance]),\n otherNode.form === target.form && updateValueIfChanged(otherNode);\n }\n break a;\n case \"textarea\":\n updateTextarea(target, props.value, props.defaultValue);\n break a;\n case \"select\":\n (internalInstance = props.value),\n null != internalInstance &&\n updateOptions(target, !!props.multiple, internalInstance, !1);\n }\n }\n}\nvar isInsideEventHandler = !1;\nfunction batchedUpdates$1(fn, a, b) {\n if (isInsideEventHandler) return fn(a, b);\n isInsideEventHandler = !0;\n try {\n var JSCompiler_inline_result = fn(a);\n return JSCompiler_inline_result;\n } finally {\n if (\n ((isInsideEventHandler = !1),\n null !== restoreTarget || null !== restoreQueue)\n )\n if (\n (flushSyncWork$1(),\n restoreTarget &&\n ((a = restoreTarget),\n (fn = restoreQueue),\n (restoreQueue = restoreTarget = null),\n restoreStateOfTarget(a),\n fn))\n )\n for (a = 0; a < fn.length; a++) restoreStateOfTarget(fn[a]);\n }\n}\nfunction getListener(inst, registrationName) {\n var stateNode = inst.stateNode;\n if (null === stateNode) return null;\n var props = stateNode[internalPropsKey] || null;\n if (null === props) return null;\n stateNode = props[registrationName];\n a: switch (registrationName) {\n case \"onClick\":\n case \"onClickCapture\":\n case \"onDoubleClick\":\n case \"onDoubleClickCapture\":\n case \"onMouseDown\":\n case \"onMouseDownCapture\":\n case \"onMouseMove\":\n case \"onMouseMoveCapture\":\n case \"onMouseUp\":\n case \"onMouseUpCapture\":\n case \"onMouseEnter\":\n (props = !props.disabled) ||\n ((inst = inst.type),\n (props = !(\n \"button\" === inst ||\n \"input\" === inst ||\n \"select\" === inst ||\n \"textarea\" === inst\n )));\n inst = !props;\n break a;\n default:\n inst = !1;\n }\n if (inst) return null;\n if (stateNode && \"function\" !== typeof stateNode)\n throw Error(\n formatProdErrorMessage(231, registrationName, typeof stateNode)\n );\n return stateNode;\n}\nvar canUseDOM = !(\n \"undefined\" === typeof window ||\n \"undefined\" === typeof window.document ||\n \"undefined\" === typeof window.document.createElement\n ),\n passiveBrowserEventsSupported = !1;\nif (canUseDOM)\n try {\n var options = {};\n Object.defineProperty(options, \"passive\", {\n get: function () {\n passiveBrowserEventsSupported = !0;\n }\n });\n window.addEventListener(\"test\", options, options);\n window.removeEventListener(\"test\", options, options);\n } catch (e) {\n passiveBrowserEventsSupported = !1;\n }\nvar root = null,\n startText = null,\n fallbackText = null;\nfunction getData() {\n if (fallbackText) return fallbackText;\n var start,\n startValue = startText,\n startLength = startValue.length,\n end,\n endValue = \"value\" in root ? root.value : root.textContent,\n endLength = endValue.length;\n for (\n start = 0;\n start < startLength && startValue[start] === endValue[start];\n start++\n );\n var minEnd = startLength - start;\n for (\n end = 1;\n end <= minEnd &&\n startValue[startLength - end] === endValue[endLength - end];\n end++\n );\n return (fallbackText = endValue.slice(start, 1 < end ? 1 - end : void 0));\n}\nfunction getEventCharCode(nativeEvent) {\n var keyCode = nativeEvent.keyCode;\n \"charCode\" in nativeEvent\n ? ((nativeEvent = nativeEvent.charCode),\n 0 === nativeEvent && 13 === keyCode && (nativeEvent = 13))\n : (nativeEvent = keyCode);\n 10 === nativeEvent && (nativeEvent = 13);\n return 32 <= nativeEvent || 13 === nativeEvent ? nativeEvent : 0;\n}\nfunction functionThatReturnsTrue() {\n return !0;\n}\nfunction functionThatReturnsFalse() {\n return !1;\n}\nfunction createSyntheticEvent(Interface) {\n function SyntheticBaseEvent(\n reactName,\n reactEventType,\n targetInst,\n nativeEvent,\n nativeEventTarget\n ) {\n this._reactName = reactName;\n this._targetInst = targetInst;\n this.type = reactEventType;\n this.nativeEvent = nativeEvent;\n this.target = nativeEventTarget;\n this.currentTarget = null;\n for (var propName in Interface)\n Interface.hasOwnProperty(propName) &&\n ((reactName = Interface[propName]),\n (this[propName] = reactName\n ? reactName(nativeEvent)\n : nativeEvent[propName]));\n this.isDefaultPrevented = (\n null != nativeEvent.defaultPrevented\n ? nativeEvent.defaultPrevented\n : !1 === nativeEvent.returnValue\n )\n ? functionThatReturnsTrue\n : functionThatReturnsFalse;\n this.isPropagationStopped = functionThatReturnsFalse;\n return this;\n }\n assign(SyntheticBaseEvent.prototype, {\n preventDefault: function () {\n this.defaultPrevented = !0;\n var event = this.nativeEvent;\n event &&\n (event.preventDefault\n ? event.preventDefault()\n : \"unknown\" !== typeof event.returnValue && (event.returnValue = !1),\n (this.isDefaultPrevented = functionThatReturnsTrue));\n },\n stopPropagation: function () {\n var event = this.nativeEvent;\n event &&\n (event.stopPropagation\n ? event.stopPropagation()\n : \"unknown\" !== typeof event.cancelBubble &&\n (event.cancelBubble = !0),\n (this.isPropagationStopped = functionThatReturnsTrue));\n },\n persist: function () {},\n isPersistent: functionThatReturnsTrue\n });\n return SyntheticBaseEvent;\n}\nvar EventInterface = {\n eventPhase: 0,\n bubbles: 0,\n cancelable: 0,\n timeStamp: function (event) {\n return event.timeStamp || Date.now();\n },\n defaultPrevented: 0,\n isTrusted: 0\n },\n SyntheticEvent = createSyntheticEvent(EventInterface),\n UIEventInterface = assign({}, EventInterface, { view: 0, detail: 0 }),\n SyntheticUIEvent = createSyntheticEvent(UIEventInterface),\n lastMovementX,\n lastMovementY,\n lastMouseEvent,\n MouseEventInterface = assign({}, UIEventInterface, {\n screenX: 0,\n screenY: 0,\n clientX: 0,\n clientY: 0,\n pageX: 0,\n pageY: 0,\n ctrlKey: 0,\n shiftKey: 0,\n altKey: 0,\n metaKey: 0,\n getModifierState: getEventModifierState,\n button: 0,\n buttons: 0,\n relatedTarget: function (event) {\n return void 0 === event.relatedTarget\n ? event.fromElement === event.srcElement\n ? event.toElement\n : event.fromElement\n : event.relatedTarget;\n },\n movementX: function (event) {\n if (\"movementX\" in event) return event.movementX;\n event !== lastMouseEvent &&\n (lastMouseEvent && \"mousemove\" === event.type\n ? ((lastMovementX = event.screenX - lastMouseEvent.screenX),\n (lastMovementY = event.screenY - lastMouseEvent.screenY))\n : (lastMovementY = lastMovementX = 0),\n (lastMouseEvent = event));\n return lastMovementX;\n },\n movementY: function (event) {\n return \"movementY\" in event ? event.movementY : lastMovementY;\n }\n }),\n SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface),\n DragEventInterface = assign({}, MouseEventInterface, { dataTransfer: 0 }),\n SyntheticDragEvent = createSyntheticEvent(DragEventInterface),\n FocusEventInterface = assign({}, UIEventInterface, { relatedTarget: 0 }),\n SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface),\n AnimationEventInterface = assign({}, EventInterface, {\n animationName: 0,\n elapsedTime: 0,\n pseudoElement: 0\n }),\n SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface),\n ClipboardEventInterface = assign({}, EventInterface, {\n clipboardData: function (event) {\n return \"clipboardData\" in event\n ? event.clipboardData\n : window.clipboardData;\n }\n }),\n SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface),\n CompositionEventInterface = assign({}, EventInterface, { data: 0 }),\n SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface),\n normalizeKey = {\n Esc: \"Escape\",\n Spacebar: \" \",\n Left: \"ArrowLeft\",\n Up: \"ArrowUp\",\n Right: \"ArrowRight\",\n Down: \"ArrowDown\",\n Del: \"Delete\",\n Win: \"OS\",\n Menu: \"ContextMenu\",\n Apps: \"ContextMenu\",\n Scroll: \"ScrollLock\",\n MozPrintableKey: \"Unidentified\"\n },\n translateToKey = {\n 8: \"Backspace\",\n 9: \"Tab\",\n 12: \"Clear\",\n 13: \"Enter\",\n 16: \"Shift\",\n 17: \"Control\",\n 18: \"Alt\",\n 19: \"Pause\",\n 20: \"CapsLock\",\n 27: \"Escape\",\n 32: \" \",\n 33: \"PageUp\",\n 34: \"PageDown\",\n 35: \"End\",\n 36: \"Home\",\n 37: \"ArrowLeft\",\n 38: \"ArrowUp\",\n 39: \"ArrowRight\",\n 40: \"ArrowDown\",\n 45: \"Insert\",\n 46: \"Delete\",\n 112: \"F1\",\n 113: \"F2\",\n 114: \"F3\",\n 115: \"F4\",\n 116: \"F5\",\n 117: \"F6\",\n 118: \"F7\",\n 119: \"F8\",\n 120: \"F9\",\n 121: \"F10\",\n 122: \"F11\",\n 123: \"F12\",\n 144: \"NumLock\",\n 145: \"ScrollLock\",\n 224: \"Meta\"\n },\n modifierKeyToProp = {\n Alt: \"altKey\",\n Control: \"ctrlKey\",\n Meta: \"metaKey\",\n Shift: \"shiftKey\"\n };\nfunction modifierStateGetter(keyArg) {\n var nativeEvent = this.nativeEvent;\n return nativeEvent.getModifierState\n ? nativeEvent.getModifierState(keyArg)\n : (keyArg = modifierKeyToProp[keyArg])\n ? !!nativeEvent[keyArg]\n : !1;\n}\nfunction getEventModifierState() {\n return modifierStateGetter;\n}\nvar KeyboardEventInterface = assign({}, UIEventInterface, {\n key: function (nativeEvent) {\n if (nativeEvent.key) {\n var key = normalizeKey[nativeEvent.key] || nativeEvent.key;\n if (\"Unidentified\" !== key) return key;\n }\n return \"keypress\" === nativeEvent.type\n ? ((nativeEvent = getEventCharCode(nativeEvent)),\n 13 === nativeEvent ? \"Enter\" : String.fromCharCode(nativeEvent))\n : \"keydown\" === nativeEvent.type || \"keyup\" === nativeEvent.type\n ? translateToKey[nativeEvent.keyCode] || \"Unidentified\"\n : \"\";\n },\n code: 0,\n location: 0,\n ctrlKey: 0,\n shiftKey: 0,\n altKey: 0,\n metaKey: 0,\n repeat: 0,\n locale: 0,\n getModifierState: getEventModifierState,\n charCode: function (event) {\n return \"keypress\" === event.type ? getEventCharCode(event) : 0;\n },\n keyCode: function (event) {\n return \"keydown\" === event.type || \"keyup\" === event.type\n ? event.keyCode\n : 0;\n },\n which: function (event) {\n return \"keypress\" === event.type\n ? getEventCharCode(event)\n : \"keydown\" === event.type || \"keyup\" === event.type\n ? event.keyCode\n : 0;\n }\n }),\n SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface),\n PointerEventInterface = assign({}, MouseEventInterface, {\n pointerId: 0,\n width: 0,\n height: 0,\n pressure: 0,\n tangentialPressure: 0,\n tiltX: 0,\n tiltY: 0,\n twist: 0,\n pointerType: 0,\n isPrimary: 0\n }),\n SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface),\n TouchEventInterface = assign({}, UIEventInterface, {\n touches: 0,\n targetTouches: 0,\n changedTouches: 0,\n altKey: 0,\n metaKey: 0,\n ctrlKey: 0,\n shiftKey: 0,\n getModifierState: getEventModifierState\n }),\n SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface),\n TransitionEventInterface = assign({}, EventInterface, {\n propertyName: 0,\n elapsedTime: 0,\n pseudoElement: 0\n }),\n SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface),\n WheelEventInterface = assign({}, MouseEventInterface, {\n deltaX: function (event) {\n return \"deltaX\" in event\n ? event.deltaX\n : \"wheelDeltaX\" in event\n ? -event.wheelDeltaX\n : 0;\n },\n deltaY: function (event) {\n return \"deltaY\" in event\n ? event.deltaY\n : \"wheelDeltaY\" in event\n ? -event.wheelDeltaY\n : \"wheelDelta\" in event\n ? -event.wheelDelta\n : 0;\n },\n deltaZ: 0,\n deltaMode: 0\n }),\n SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface),\n ToggleEventInterface = assign({}, EventInterface, {\n newState: 0,\n oldState: 0\n }),\n SyntheticToggleEvent = createSyntheticEvent(ToggleEventInterface),\n END_KEYCODES = [9, 13, 27, 32],\n canUseCompositionEvent = canUseDOM && \"CompositionEvent\" in window,\n documentMode = null;\ncanUseDOM &&\n \"documentMode\" in document &&\n (documentMode = document.documentMode);\nvar canUseTextInputEvent = canUseDOM && \"TextEvent\" in window && !documentMode,\n useFallbackCompositionData =\n canUseDOM &&\n (!canUseCompositionEvent ||\n (documentMode && 8 < documentMode && 11 >= documentMode)),\n SPACEBAR_CHAR = String.fromCharCode(32),\n hasSpaceKeypress = !1;\nfunction isFallbackCompositionEnd(domEventName, nativeEvent) {\n switch (domEventName) {\n case \"keyup\":\n return -1 !== END_KEYCODES.indexOf(nativeEvent.keyCode);\n case \"keydown\":\n return 229 !== nativeEvent.keyCode;\n case \"keypress\":\n case \"mousedown\":\n case \"focusout\":\n return !0;\n default:\n return !1;\n }\n}\nfunction getDataFromCustomEvent(nativeEvent) {\n nativeEvent = nativeEvent.detail;\n return \"object\" === typeof nativeEvent && \"data\" in nativeEvent\n ? nativeEvent.data\n : null;\n}\nvar isComposing = !1;\nfunction getNativeBeforeInputChars(domEventName, nativeEvent) {\n switch (domEventName) {\n case \"compositionend\":\n return getDataFromCustomEvent(nativeEvent);\n case \"keypress\":\n if (32 !== nativeEvent.which) return null;\n hasSpaceKeypress = !0;\n return SPACEBAR_CHAR;\n case \"textInput\":\n return (\n (domEventName = nativeEvent.data),\n domEventName === SPACEBAR_CHAR && hasSpaceKeypress ? null : domEventName\n );\n default:\n return null;\n }\n}\nfunction getFallbackBeforeInputChars(domEventName, nativeEvent) {\n if (isComposing)\n return \"compositionend\" === domEventName ||\n (!canUseCompositionEvent &&\n isFallbackCompositionEnd(domEventName, nativeEvent))\n ? ((domEventName = getData()),\n (fallbackText = startText = root = null),\n (isComposing = !1),\n domEventName)\n : null;\n switch (domEventName) {\n case \"paste\":\n return null;\n case \"keypress\":\n if (\n !(nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) ||\n (nativeEvent.ctrlKey && nativeEvent.altKey)\n ) {\n if (nativeEvent.char && 1 < nativeEvent.char.length)\n return nativeEvent.char;\n if (nativeEvent.which) return String.fromCharCode(nativeEvent.which);\n }\n return null;\n case \"compositionend\":\n return useFallbackCompositionData && \"ko\" !== nativeEvent.locale\n ? null\n : nativeEvent.data;\n default:\n return null;\n }\n}\nvar supportedInputTypes = {\n color: !0,\n date: !0,\n datetime: !0,\n \"datetime-local\": !0,\n email: !0,\n month: !0,\n number: !0,\n password: !0,\n range: !0,\n search: !0,\n tel: !0,\n text: !0,\n time: !0,\n url: !0,\n week: !0\n};\nfunction isTextInputElement(elem) {\n var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n return \"input\" === nodeName\n ? !!supportedInputTypes[elem.type]\n : \"textarea\" === nodeName\n ? !0\n : !1;\n}\nfunction createAndAccumulateChangeEvent(\n dispatchQueue,\n inst,\n nativeEvent,\n target\n) {\n restoreTarget\n ? restoreQueue\n ? restoreQueue.push(target)\n : (restoreQueue = [target])\n : (restoreTarget = target);\n inst = accumulateTwoPhaseListeners(inst, \"onChange\");\n 0 < inst.length &&\n ((nativeEvent = new SyntheticEvent(\n \"onChange\",\n \"change\",\n null,\n nativeEvent,\n target\n )),\n dispatchQueue.push({ event: nativeEvent, listeners: inst }));\n}\nvar activeElement$1 = null,\n activeElementInst$1 = null;\nfunction runEventInBatch(dispatchQueue) {\n processDispatchQueue(dispatchQueue, 0);\n}\nfunction getInstIfValueChanged(targetInst) {\n var targetNode = getNodeFromInstance(targetInst);\n if (updateValueIfChanged(targetNode)) return targetInst;\n}\nfunction getTargetInstForChangeEvent(domEventName, targetInst) {\n if (\"change\" === domEventName) return targetInst;\n}\nvar isInputEventSupported = !1;\nif (canUseDOM) {\n var JSCompiler_inline_result$jscomp$286;\n if (canUseDOM) {\n var isSupported$jscomp$inline_427 = \"oninput\" in document;\n if (!isSupported$jscomp$inline_427) {\n var element$jscomp$inline_428 = document.createElement(\"div\");\n element$jscomp$inline_428.setAttribute(\"oninput\", \"return;\");\n isSupported$jscomp$inline_427 =\n \"function\" === typeof element$jscomp$inline_428.oninput;\n }\n JSCompiler_inline_result$jscomp$286 = isSupported$jscomp$inline_427;\n } else JSCompiler_inline_result$jscomp$286 = !1;\n isInputEventSupported =\n JSCompiler_inline_result$jscomp$286 &&\n (!document.documentMode || 9 < document.documentMode);\n}\nfunction stopWatchingForValueChange() {\n activeElement$1 &&\n (activeElement$1.detachEvent(\"onpropertychange\", handlePropertyChange),\n (activeElementInst$1 = activeElement$1 = null));\n}\nfunction handlePropertyChange(nativeEvent) {\n if (\n \"value\" === nativeEvent.propertyName &&\n getInstIfValueChanged(activeElementInst$1)\n ) {\n var dispatchQueue = [];\n createAndAccumulateChangeEvent(\n dispatchQueue,\n activeElementInst$1,\n nativeEvent,\n getEventTarget(nativeEvent)\n );\n batchedUpdates$1(runEventInBatch, dispatchQueue);\n }\n}\nfunction handleEventsForInputEventPolyfill(domEventName, target, targetInst) {\n \"focusin\" === domEventName\n ? (stopWatchingForValueChange(),\n (activeElement$1 = target),\n (activeElementInst$1 = targetInst),\n activeElement$1.attachEvent(\"onpropertychange\", handlePropertyChange))\n : \"focusout\" === domEventName && stopWatchingForValueChange();\n}\nfunction getTargetInstForInputEventPolyfill(domEventName) {\n if (\n \"selectionchange\" === domEventName ||\n \"keyup\" === domEventName ||\n \"keydown\" === domEventName\n )\n return getInstIfValueChanged(activeElementInst$1);\n}\nfunction getTargetInstForClickEvent(domEventName, targetInst) {\n if (\"click\" === domEventName) return getInstIfValueChanged(targetInst);\n}\nfunction getTargetInstForInputOrChangeEvent(domEventName, targetInst) {\n if (\"input\" === domEventName || \"change\" === domEventName)\n return getInstIfValueChanged(targetInst);\n}\nfunction is(x, y) {\n return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);\n}\nvar objectIs = \"function\" === typeof Object.is ? Object.is : is;\nfunction shallowEqual(objA, objB) {\n if (objectIs(objA, objB)) return !0;\n if (\n \"object\" !== typeof objA ||\n null === objA ||\n \"object\" !== typeof objB ||\n null === objB\n )\n return !1;\n var keysA = Object.keys(objA),\n keysB = Object.keys(objB);\n if (keysA.length !== keysB.length) return !1;\n for (keysB = 0; keysB < keysA.length; keysB++) {\n var currentKey = keysA[keysB];\n if (\n !hasOwnProperty.call(objB, currentKey) ||\n !objectIs(objA[currentKey], objB[currentKey])\n )\n return !1;\n }\n return !0;\n}\nfunction getLeafNode(node) {\n for (; node && node.firstChild; ) node = node.firstChild;\n return node;\n}\nfunction getNodeForCharacterOffset(root, offset) {\n var node = getLeafNode(root);\n root = 0;\n for (var nodeEnd; node; ) {\n if (3 === node.nodeType) {\n nodeEnd = root + node.textContent.length;\n if (root <= offset && nodeEnd >= offset)\n return { node: node, offset: offset - root };\n root = nodeEnd;\n }\n a: {\n for (; node; ) {\n if (node.nextSibling) {\n node = node.nextSibling;\n break a;\n }\n node = node.parentNode;\n }\n node = void 0;\n }\n node = getLeafNode(node);\n }\n}\nfunction containsNode(outerNode, innerNode) {\n return outerNode && innerNode\n ? outerNode === innerNode\n ? !0\n : outerNode && 3 === outerNode.nodeType\n ? !1\n : innerNode && 3 === innerNode.nodeType\n ? containsNode(outerNode, innerNode.parentNode)\n : \"contains\" in outerNode\n ? outerNode.contains(innerNode)\n : outerNode.compareDocumentPosition\n ? !!(outerNode.compareDocumentPosition(innerNode) & 16)\n : !1\n : !1;\n}\nfunction getActiveElementDeep(containerInfo) {\n containerInfo =\n null != containerInfo &&\n null != containerInfo.ownerDocument &&\n null != containerInfo.ownerDocument.defaultView\n ? containerInfo.ownerDocument.defaultView\n : window;\n for (\n var element = getActiveElement(containerInfo.document);\n element instanceof containerInfo.HTMLIFrameElement;\n\n ) {\n try {\n var JSCompiler_inline_result =\n \"string\" === typeof element.contentWindow.location.href;\n } catch (err) {\n JSCompiler_inline_result = !1;\n }\n if (JSCompiler_inline_result) containerInfo = element.contentWindow;\n else break;\n element = getActiveElement(containerInfo.document);\n }\n return element;\n}\nfunction hasSelectionCapabilities(elem) {\n var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n return (\n nodeName &&\n ((\"input\" === nodeName &&\n (\"text\" === elem.type ||\n \"search\" === elem.type ||\n \"tel\" === elem.type ||\n \"url\" === elem.type ||\n \"password\" === elem.type)) ||\n \"textarea\" === nodeName ||\n \"true\" === elem.contentEditable)\n );\n}\nvar skipSelectionChangeEvent =\n canUseDOM && \"documentMode\" in document && 11 >= document.documentMode,\n activeElement = null,\n activeElementInst = null,\n lastSelection = null,\n mouseDown = !1;\nfunction constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {\n var doc =\n nativeEventTarget.window === nativeEventTarget\n ? nativeEventTarget.document\n : 9 === nativeEventTarget.nodeType\n ? nativeEventTarget\n : nativeEventTarget.ownerDocument;\n mouseDown ||\n null == activeElement ||\n activeElement !== getActiveElement(doc) ||\n ((doc = activeElement),\n \"selectionStart\" in doc && hasSelectionCapabilities(doc)\n ? (doc = { start: doc.selectionStart, end: doc.selectionEnd })\n : ((doc = (\n (doc.ownerDocument && doc.ownerDocument.defaultView) ||\n window\n ).getSelection()),\n (doc = {\n anchorNode: doc.anchorNode,\n anchorOffset: doc.anchorOffset,\n focusNode: doc.focusNode,\n focusOffset: doc.focusOffset\n })),\n (lastSelection && shallowEqual(lastSelection, doc)) ||\n ((lastSelection = doc),\n (doc = accumulateTwoPhaseListeners(activeElementInst, \"onSelect\")),\n 0 < doc.length &&\n ((nativeEvent = new SyntheticEvent(\n \"onSelect\",\n \"select\",\n null,\n nativeEvent,\n nativeEventTarget\n )),\n dispatchQueue.push({ event: nativeEvent, listeners: doc }),\n (nativeEvent.target = activeElement))));\n}\nfunction makePrefixMap(styleProp, eventName) {\n var prefixes = {};\n prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();\n prefixes[\"Webkit\" + styleProp] = \"webkit\" + eventName;\n prefixes[\"Moz\" + styleProp] = \"moz\" + eventName;\n return prefixes;\n}\nvar vendorPrefixes = {\n animationend: makePrefixMap(\"Animation\", \"AnimationEnd\"),\n animationiteration: makePrefixMap(\"Animation\", \"AnimationIteration\"),\n animationstart: makePrefixMap(\"Animation\", \"AnimationStart\"),\n transitionrun: makePrefixMap(\"Transition\", \"TransitionRun\"),\n transitionstart: makePrefixMap(\"Transition\", \"TransitionStart\"),\n transitioncancel: makePrefixMap(\"Transition\", \"TransitionCancel\"),\n transitionend: makePrefixMap(\"Transition\", \"TransitionEnd\")\n },\n prefixedEventNames = {},\n style = {};\ncanUseDOM &&\n ((style = document.createElement(\"div\").style),\n \"AnimationEvent\" in window ||\n (delete vendorPrefixes.animationend.animation,\n delete vendorPrefixes.animationiteration.animation,\n delete vendorPrefixes.animationstart.animation),\n \"TransitionEvent\" in window ||\n delete vendorPrefixes.transitionend.transition);\nfunction getVendorPrefixedEventName(eventName) {\n if (prefixedEventNames[eventName]) return prefixedEventNames[eventName];\n if (!vendorPrefixes[eventName]) return eventName;\n var prefixMap = vendorPrefixes[eventName],\n styleProp;\n for (styleProp in prefixMap)\n if (prefixMap.hasOwnProperty(styleProp) && styleProp in style)\n return (prefixedEventNames[eventName] = prefixMap[styleProp]);\n return eventName;\n}\nvar ANIMATION_END = getVendorPrefixedEventName(\"animationend\"),\n ANIMATION_ITERATION = getVendorPrefixedEventName(\"animationiteration\"),\n ANIMATION_START = getVendorPrefixedEventName(\"animationstart\"),\n TRANSITION_RUN = getVendorPrefixedEventName(\"transitionrun\"),\n TRANSITION_START = getVendorPrefixedEventName(\"transitionstart\"),\n TRANSITION_CANCEL = getVendorPrefixedEventName(\"transitioncancel\"),\n TRANSITION_END = getVendorPrefixedEventName(\"transitionend\"),\n topLevelEventsToReactNames = new Map(),\n simpleEventPluginEvents =\n \"abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel\".split(\n \" \"\n );\nsimpleEventPluginEvents.push(\"scrollEnd\");\nfunction registerSimpleEvent(domEventName, reactName) {\n topLevelEventsToReactNames.set(domEventName, reactName);\n registerTwoPhaseEvent(reactName, [domEventName]);\n}\nvar reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n },\n concurrentQueues = [],\n concurrentQueuesIndex = 0,\n concurrentlyUpdatedLanes = 0;\nfunction finishQueueingConcurrentUpdates() {\n for (\n var endIndex = concurrentQueuesIndex,\n i = (concurrentlyUpdatedLanes = concurrentQueuesIndex = 0);\n i < endIndex;\n\n ) {\n var fiber = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var queue = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var update = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var lane = concurrentQueues[i];\n concurrentQueues[i++] = null;\n if (null !== queue && null !== update) {\n var pending = queue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n queue.pending = update;\n }\n 0 !== lane && markUpdateLaneFromFiberToRoot(fiber, update, lane);\n }\n}\nfunction enqueueUpdate$1(fiber, queue, update, lane) {\n concurrentQueues[concurrentQueuesIndex++] = fiber;\n concurrentQueues[concurrentQueuesIndex++] = queue;\n concurrentQueues[concurrentQueuesIndex++] = update;\n concurrentQueues[concurrentQueuesIndex++] = lane;\n concurrentlyUpdatedLanes |= lane;\n fiber.lanes |= lane;\n fiber = fiber.alternate;\n null !== fiber && (fiber.lanes |= lane);\n}\nfunction enqueueConcurrentHookUpdate(fiber, queue, update, lane) {\n enqueueUpdate$1(fiber, queue, update, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction enqueueConcurrentRenderForLane(fiber, lane) {\n enqueueUpdate$1(fiber, null, null, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) {\n sourceFiber.lanes |= lane;\n var alternate = sourceFiber.alternate;\n null !== alternate && (alternate.lanes |= lane);\n for (var isHidden = !1, parent = sourceFiber.return; null !== parent; )\n (parent.childLanes |= lane),\n (alternate = parent.alternate),\n null !== alternate && (alternate.childLanes |= lane),\n 22 === parent.tag &&\n ((sourceFiber = parent.stateNode),\n null === sourceFiber || sourceFiber._visibility & 1 || (isHidden = !0)),\n (sourceFiber = parent),\n (parent = parent.return);\n return 3 === sourceFiber.tag\n ? ((parent = sourceFiber.stateNode),\n isHidden &&\n null !== update &&\n ((isHidden = 31 - clz32(lane)),\n (sourceFiber = parent.hiddenUpdates),\n (alternate = sourceFiber[isHidden]),\n null === alternate\n ? (sourceFiber[isHidden] = [update])\n : alternate.push(update),\n (update.lane = lane | 536870912)),\n parent)\n : null;\n}\nfunction getRootForUpdatedFiber(sourceFiber) {\n if (50 < nestedUpdateCount)\n throw (\n ((nestedUpdateCount = 0),\n (rootWithNestedUpdates = null),\n Error(formatProdErrorMessage(185)))\n );\n for (var parent = sourceFiber.return; null !== parent; )\n (sourceFiber = parent), (parent = sourceFiber.return);\n return 3 === sourceFiber.tag ? sourceFiber.stateNode : null;\n}\nvar emptyContextObject = {};\nfunction FiberNode(tag, pendingProps, key, mode) {\n this.tag = tag;\n this.key = key;\n this.sibling =\n this.child =\n this.return =\n this.stateNode =\n this.type =\n this.elementType =\n null;\n this.index = 0;\n this.refCleanup = this.ref = null;\n this.pendingProps = pendingProps;\n this.dependencies =\n this.memoizedState =\n this.updateQueue =\n this.memoizedProps =\n null;\n this.mode = mode;\n this.subtreeFlags = this.flags = 0;\n this.deletions = null;\n this.childLanes = this.lanes = 0;\n this.alternate = null;\n}\nfunction createFiberImplClass(tag, pendingProps, key, mode) {\n return new FiberNode(tag, pendingProps, key, mode);\n}\nfunction shouldConstruct(Component) {\n Component = Component.prototype;\n return !(!Component || !Component.isReactComponent);\n}\nfunction createWorkInProgress(current, pendingProps) {\n var workInProgress = current.alternate;\n null === workInProgress\n ? ((workInProgress = createFiberImplClass(\n current.tag,\n pendingProps,\n current.key,\n current.mode\n )),\n (workInProgress.elementType = current.elementType),\n (workInProgress.type = current.type),\n (workInProgress.stateNode = current.stateNode),\n (workInProgress.alternate = current),\n (current.alternate = workInProgress))\n : ((workInProgress.pendingProps = pendingProps),\n (workInProgress.type = current.type),\n (workInProgress.flags = 0),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.deletions = null));\n workInProgress.flags = current.flags & 65011712;\n workInProgress.childLanes = current.childLanes;\n workInProgress.lanes = current.lanes;\n workInProgress.child = current.child;\n workInProgress.memoizedProps = current.memoizedProps;\n workInProgress.memoizedState = current.memoizedState;\n workInProgress.updateQueue = current.updateQueue;\n pendingProps = current.dependencies;\n workInProgress.dependencies =\n null === pendingProps\n ? null\n : { lanes: pendingProps.lanes, firstContext: pendingProps.firstContext };\n workInProgress.sibling = current.sibling;\n workInProgress.index = current.index;\n workInProgress.ref = current.ref;\n workInProgress.refCleanup = current.refCleanup;\n return workInProgress;\n}\nfunction resetWorkInProgress(workInProgress, renderLanes) {\n workInProgress.flags &= 65011714;\n var current = workInProgress.alternate;\n null === current\n ? ((workInProgress.childLanes = 0),\n (workInProgress.lanes = renderLanes),\n (workInProgress.child = null),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.memoizedProps = null),\n (workInProgress.memoizedState = null),\n (workInProgress.updateQueue = null),\n (workInProgress.dependencies = null),\n (workInProgress.stateNode = null))\n : ((workInProgress.childLanes = current.childLanes),\n (workInProgress.lanes = current.lanes),\n (workInProgress.child = current.child),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.deletions = null),\n (workInProgress.memoizedProps = current.memoizedProps),\n (workInProgress.memoizedState = current.memoizedState),\n (workInProgress.updateQueue = current.updateQueue),\n (workInProgress.type = current.type),\n (renderLanes = current.dependencies),\n (workInProgress.dependencies =\n null === renderLanes\n ? null\n : {\n lanes: renderLanes.lanes,\n firstContext: renderLanes.firstContext\n }));\n return workInProgress;\n}\nfunction createFiberFromTypeAndProps(\n type,\n key,\n pendingProps,\n owner,\n mode,\n lanes\n) {\n var fiberTag = 0;\n owner = type;\n if (\"function\" === typeof type) shouldConstruct(type) && (fiberTag = 1);\n else if (\"string\" === typeof type)\n fiberTag = isHostHoistableType(\n type,\n pendingProps,\n contextStackCursor.current\n )\n ? 26\n : \"html\" === type || \"head\" === type || \"body\" === type\n ? 27\n : 5;\n else\n a: switch (type) {\n case REACT_ACTIVITY_TYPE:\n return (\n (type = createFiberImplClass(31, pendingProps, key, mode)),\n (type.elementType = REACT_ACTIVITY_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_FRAGMENT_TYPE:\n return createFiberFromFragment(pendingProps.children, mode, lanes, key);\n case REACT_STRICT_MODE_TYPE:\n fiberTag = 8;\n mode |= 24;\n break;\n case REACT_PROFILER_TYPE:\n return (\n (type = createFiberImplClass(12, pendingProps, key, mode | 2)),\n (type.elementType = REACT_PROFILER_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_SUSPENSE_TYPE:\n return (\n (type = createFiberImplClass(13, pendingProps, key, mode)),\n (type.elementType = REACT_SUSPENSE_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_SUSPENSE_LIST_TYPE:\n return (\n (type = createFiberImplClass(19, pendingProps, key, mode)),\n (type.elementType = REACT_SUSPENSE_LIST_TYPE),\n (type.lanes = lanes),\n type\n );\n default:\n if (\"object\" === typeof type && null !== type)\n switch (type.$$typeof) {\n case REACT_CONTEXT_TYPE:\n fiberTag = 10;\n break a;\n case REACT_CONSUMER_TYPE:\n fiberTag = 9;\n break a;\n case REACT_FORWARD_REF_TYPE:\n fiberTag = 11;\n break a;\n case REACT_MEMO_TYPE:\n fiberTag = 14;\n break a;\n case REACT_LAZY_TYPE:\n fiberTag = 16;\n owner = null;\n break a;\n }\n fiberTag = 29;\n pendingProps = Error(\n formatProdErrorMessage(130, null === type ? \"null\" : typeof type, \"\")\n );\n owner = null;\n }\n key = createFiberImplClass(fiberTag, pendingProps, key, mode);\n key.elementType = type;\n key.type = owner;\n key.lanes = lanes;\n return key;\n}\nfunction createFiberFromFragment(elements, mode, lanes, key) {\n elements = createFiberImplClass(7, elements, key, mode);\n elements.lanes = lanes;\n return elements;\n}\nfunction createFiberFromText(content, mode, lanes) {\n content = createFiberImplClass(6, content, null, mode);\n content.lanes = lanes;\n return content;\n}\nfunction createFiberFromDehydratedFragment(dehydratedNode) {\n var fiber = createFiberImplClass(18, null, null, 0);\n fiber.stateNode = dehydratedNode;\n return fiber;\n}\nfunction createFiberFromPortal(portal, mode, lanes) {\n mode = createFiberImplClass(\n 4,\n null !== portal.children ? portal.children : [],\n portal.key,\n mode\n );\n mode.lanes = lanes;\n mode.stateNode = {\n containerInfo: portal.containerInfo,\n pendingChildren: null,\n implementation: portal.implementation\n };\n return mode;\n}\nvar CapturedStacks = new WeakMap();\nfunction createCapturedValueAtFiber(value, source) {\n if (\"object\" === typeof value && null !== value) {\n var existing = CapturedStacks.get(value);\n if (void 0 !== existing) return existing;\n source = {\n value: value,\n source: source,\n stack: getStackByFiberInDevAndProd(source)\n };\n CapturedStacks.set(value, source);\n return source;\n }\n return {\n value: value,\n source: source,\n stack: getStackByFiberInDevAndProd(source)\n };\n}\nvar forkStack = [],\n forkStackIndex = 0,\n treeForkProvider = null,\n treeForkCount = 0,\n idStack = [],\n idStackIndex = 0,\n treeContextProvider = null,\n treeContextId = 1,\n treeContextOverflow = \"\";\nfunction pushTreeFork(workInProgress, totalChildren) {\n forkStack[forkStackIndex++] = treeForkCount;\n forkStack[forkStackIndex++] = treeForkProvider;\n treeForkProvider = workInProgress;\n treeForkCount = totalChildren;\n}\nfunction pushTreeId(workInProgress, totalChildren, index) {\n idStack[idStackIndex++] = treeContextId;\n idStack[idStackIndex++] = treeContextOverflow;\n idStack[idStackIndex++] = treeContextProvider;\n treeContextProvider = workInProgress;\n var baseIdWithLeadingBit = treeContextId;\n workInProgress = treeContextOverflow;\n var baseLength = 32 - clz32(baseIdWithLeadingBit) - 1;\n baseIdWithLeadingBit &= ~(1 << baseLength);\n index += 1;\n var length = 32 - clz32(totalChildren) + baseLength;\n if (30 < length) {\n var numberOfOverflowBits = baseLength - (baseLength % 5);\n length = (\n baseIdWithLeadingBit &\n ((1 << numberOfOverflowBits) - 1)\n ).toString(32);\n baseIdWithLeadingBit >>= numberOfOverflowBits;\n baseLength -= numberOfOverflowBits;\n treeContextId =\n (1 << (32 - clz32(totalChildren) + baseLength)) |\n (index << baseLength) |\n baseIdWithLeadingBit;\n treeContextOverflow = length + workInProgress;\n } else\n (treeContextId =\n (1 << length) | (index << baseLength) | baseIdWithLeadingBit),\n (treeContextOverflow = workInProgress);\n}\nfunction pushMaterializedTreeId(workInProgress) {\n null !== workInProgress.return &&\n (pushTreeFork(workInProgress, 1), pushTreeId(workInProgress, 1, 0));\n}\nfunction popTreeContext(workInProgress) {\n for (; workInProgress === treeForkProvider; )\n (treeForkProvider = forkStack[--forkStackIndex]),\n (forkStack[forkStackIndex] = null),\n (treeForkCount = forkStack[--forkStackIndex]),\n (forkStack[forkStackIndex] = null);\n for (; workInProgress === treeContextProvider; )\n (treeContextProvider = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null),\n (treeContextOverflow = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null),\n (treeContextId = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null);\n}\nfunction restoreSuspendedTreeContext(workInProgress, suspendedContext) {\n idStack[idStackIndex++] = treeContextId;\n idStack[idStackIndex++] = treeContextOverflow;\n idStack[idStackIndex++] = treeContextProvider;\n treeContextId = suspendedContext.id;\n treeContextOverflow = suspendedContext.overflow;\n treeContextProvider = workInProgress;\n}\nvar hydrationParentFiber = null,\n nextHydratableInstance = null,\n isHydrating = !1,\n hydrationErrors = null,\n rootOrSingletonContext = !1,\n HydrationMismatchException = Error(formatProdErrorMessage(519));\nfunction throwOnHydrationMismatch(fiber) {\n var error = Error(\n formatProdErrorMessage(\n 418,\n 1 < arguments.length && void 0 !== arguments[1] && arguments[1]\n ? \"text\"\n : \"HTML\",\n \"\"\n )\n );\n queueHydrationError(createCapturedValueAtFiber(error, fiber));\n throw HydrationMismatchException;\n}\nfunction prepareToHydrateHostInstance(fiber) {\n var instance = fiber.stateNode,\n type = fiber.type,\n props = fiber.memoizedProps;\n instance[internalInstanceKey] = fiber;\n instance[internalPropsKey] = props;\n switch (type) {\n case \"dialog\":\n listenToNonDelegatedEvent(\"cancel\", instance);\n listenToNonDelegatedEvent(\"close\", instance);\n break;\n case \"iframe\":\n case \"object\":\n case \"embed\":\n listenToNonDelegatedEvent(\"load\", instance);\n break;\n case \"video\":\n case \"audio\":\n for (type = 0; type < mediaEventTypes.length; type++)\n listenToNonDelegatedEvent(mediaEventTypes[type], instance);\n break;\n case \"source\":\n listenToNonDelegatedEvent(\"error\", instance);\n break;\n case \"img\":\n case \"image\":\n case \"link\":\n listenToNonDelegatedEvent(\"error\", instance);\n listenToNonDelegatedEvent(\"load\", instance);\n break;\n case \"details\":\n listenToNonDelegatedEvent(\"toggle\", instance);\n break;\n case \"input\":\n listenToNonDelegatedEvent(\"invalid\", instance);\n initInput(\n instance,\n props.value,\n props.defaultValue,\n props.checked,\n props.defaultChecked,\n props.type,\n props.name,\n !0\n );\n break;\n case \"select\":\n listenToNonDelegatedEvent(\"invalid\", instance);\n break;\n case \"textarea\":\n listenToNonDelegatedEvent(\"invalid\", instance),\n initTextarea(instance, props.value, props.defaultValue, props.children);\n }\n type = props.children;\n (\"string\" !== typeof type &&\n \"number\" !== typeof type &&\n \"bigint\" !== typeof type) ||\n instance.textContent === \"\" + type ||\n !0 === props.suppressHydrationWarning ||\n checkForUnmatchedText(instance.textContent, type)\n ? (null != props.popover &&\n (listenToNonDelegatedEvent(\"beforetoggle\", instance),\n listenToNonDelegatedEvent(\"toggle\", instance)),\n null != props.onScroll && listenToNonDelegatedEvent(\"scroll\", instance),\n null != props.onScrollEnd &&\n listenToNonDelegatedEvent(\"scrollend\", instance),\n null != props.onClick && (instance.onclick = noop$1),\n (instance = !0))\n : (instance = !1);\n instance || throwOnHydrationMismatch(fiber, !0);\n}\nfunction popToNextHostParent(fiber) {\n for (hydrationParentFiber = fiber.return; hydrationParentFiber; )\n switch (hydrationParentFiber.tag) {\n case 5:\n case 31:\n case 13:\n rootOrSingletonContext = !1;\n return;\n case 27:\n case 3:\n rootOrSingletonContext = !0;\n return;\n default:\n hydrationParentFiber = hydrationParentFiber.return;\n }\n}\nfunction popHydrationState(fiber) {\n if (fiber !== hydrationParentFiber) return !1;\n if (!isHydrating) return popToNextHostParent(fiber), (isHydrating = !0), !1;\n var tag = fiber.tag,\n JSCompiler_temp;\n if ((JSCompiler_temp = 3 !== tag && 27 !== tag)) {\n if ((JSCompiler_temp = 5 === tag))\n (JSCompiler_temp = fiber.type),\n (JSCompiler_temp =\n !(\"form\" !== JSCompiler_temp && \"button\" !== JSCompiler_temp) ||\n shouldSetTextContent(fiber.type, fiber.memoizedProps));\n JSCompiler_temp = !JSCompiler_temp;\n }\n JSCompiler_temp && nextHydratableInstance && throwOnHydrationMismatch(fiber);\n popToNextHostParent(fiber);\n if (13 === tag) {\n fiber = fiber.memoizedState;\n fiber = null !== fiber ? fiber.dehydrated : null;\n if (!fiber) throw Error(formatProdErrorMessage(317));\n nextHydratableInstance =\n getNextHydratableInstanceAfterHydrationBoundary(fiber);\n } else if (31 === tag) {\n fiber = fiber.memoizedState;\n fiber = null !== fiber ? fiber.dehydrated : null;\n if (!fiber) throw Error(formatProdErrorMessage(317));\n nextHydratableInstance =\n getNextHydratableInstanceAfterHydrationBoundary(fiber);\n } else\n 27 === tag\n ? ((tag = nextHydratableInstance),\n isSingletonScope(fiber.type)\n ? ((fiber = previousHydratableOnEnteringScopedSingleton),\n (previousHydratableOnEnteringScopedSingleton = null),\n (nextHydratableInstance = fiber))\n : (nextHydratableInstance = tag))\n : (nextHydratableInstance = hydrationParentFiber\n ? getNextHydratable(fiber.stateNode.nextSibling)\n : null);\n return !0;\n}\nfunction resetHydrationState() {\n nextHydratableInstance = hydrationParentFiber = null;\n isHydrating = !1;\n}\nfunction upgradeHydrationErrorsToRecoverable() {\n var queuedErrors = hydrationErrors;\n null !== queuedErrors &&\n (null === workInProgressRootRecoverableErrors\n ? (workInProgressRootRecoverableErrors = queuedErrors)\n : workInProgressRootRecoverableErrors.push.apply(\n workInProgressRootRecoverableErrors,\n queuedErrors\n ),\n (hydrationErrors = null));\n return queuedErrors;\n}\nfunction queueHydrationError(error) {\n null === hydrationErrors\n ? (hydrationErrors = [error])\n : hydrationErrors.push(error);\n}\nvar valueCursor = createCursor(null),\n currentlyRenderingFiber$1 = null,\n lastContextDependency = null;\nfunction pushProvider(providerFiber, context, nextValue) {\n push(valueCursor, context._currentValue);\n context._currentValue = nextValue;\n}\nfunction popProvider(context) {\n context._currentValue = valueCursor.current;\n pop(valueCursor);\n}\nfunction scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {\n for (; null !== parent; ) {\n var alternate = parent.alternate;\n (parent.childLanes & renderLanes) !== renderLanes\n ? ((parent.childLanes |= renderLanes),\n null !== alternate && (alternate.childLanes |= renderLanes))\n : null !== alternate &&\n (alternate.childLanes & renderLanes) !== renderLanes &&\n (alternate.childLanes |= renderLanes);\n if (parent === propagationRoot) break;\n parent = parent.return;\n }\n}\nfunction propagateContextChanges(\n workInProgress,\n contexts,\n renderLanes,\n forcePropagateEntireTree\n) {\n var fiber = workInProgress.child;\n null !== fiber && (fiber.return = workInProgress);\n for (; null !== fiber; ) {\n var list = fiber.dependencies;\n if (null !== list) {\n var nextFiber = fiber.child;\n list = list.firstContext;\n a: for (; null !== list; ) {\n var dependency = list;\n list = fiber;\n for (var i = 0; i < contexts.length; i++)\n if (dependency.context === contexts[i]) {\n list.lanes |= renderLanes;\n dependency = list.alternate;\n null !== dependency && (dependency.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(\n list.return,\n renderLanes,\n workInProgress\n );\n forcePropagateEntireTree || (nextFiber = null);\n break a;\n }\n list = dependency.next;\n }\n } else if (18 === fiber.tag) {\n nextFiber = fiber.return;\n if (null === nextFiber) throw Error(formatProdErrorMessage(341));\n nextFiber.lanes |= renderLanes;\n list = nextFiber.alternate;\n null !== list && (list.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(nextFiber, renderLanes, workInProgress);\n nextFiber = null;\n } else nextFiber = fiber.child;\n if (null !== nextFiber) nextFiber.return = fiber;\n else\n for (nextFiber = fiber; null !== nextFiber; ) {\n if (nextFiber === workInProgress) {\n nextFiber = null;\n break;\n }\n fiber = nextFiber.sibling;\n if (null !== fiber) {\n fiber.return = nextFiber.return;\n nextFiber = fiber;\n break;\n }\n nextFiber = nextFiber.return;\n }\n fiber = nextFiber;\n }\n}\nfunction propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n forcePropagateEntireTree\n) {\n current = null;\n for (\n var parent = workInProgress, isInsidePropagationBailout = !1;\n null !== parent;\n\n ) {\n if (!isInsidePropagationBailout)\n if (0 !== (parent.flags & 524288)) isInsidePropagationBailout = !0;\n else if (0 !== (parent.flags & 262144)) break;\n if (10 === parent.tag) {\n var currentParent = parent.alternate;\n if (null === currentParent) throw Error(formatProdErrorMessage(387));\n currentParent = currentParent.memoizedProps;\n if (null !== currentParent) {\n var context = parent.type;\n objectIs(parent.pendingProps.value, currentParent.value) ||\n (null !== current ? current.push(context) : (current = [context]));\n }\n } else if (parent === hostTransitionProviderCursor.current) {\n currentParent = parent.alternate;\n if (null === currentParent) throw Error(formatProdErrorMessage(387));\n currentParent.memoizedState.memoizedState !==\n parent.memoizedState.memoizedState &&\n (null !== current\n ? current.push(HostTransitionContext)\n : (current = [HostTransitionContext]));\n }\n parent = parent.return;\n }\n null !== current &&\n propagateContextChanges(\n workInProgress,\n current,\n renderLanes,\n forcePropagateEntireTree\n );\n workInProgress.flags |= 262144;\n}\nfunction checkIfContextChanged(currentDependencies) {\n for (\n currentDependencies = currentDependencies.firstContext;\n null !== currentDependencies;\n\n ) {\n if (\n !objectIs(\n currentDependencies.context._currentValue,\n currentDependencies.memoizedValue\n )\n )\n return !0;\n currentDependencies = currentDependencies.next;\n }\n return !1;\n}\nfunction prepareToReadContext(workInProgress) {\n currentlyRenderingFiber$1 = workInProgress;\n lastContextDependency = null;\n workInProgress = workInProgress.dependencies;\n null !== workInProgress && (workInProgress.firstContext = null);\n}\nfunction readContext(context) {\n return readContextForConsumer(currentlyRenderingFiber$1, context);\n}\nfunction readContextDuringReconciliation(consumer, context) {\n null === currentlyRenderingFiber$1 && prepareToReadContext(consumer);\n return readContextForConsumer(consumer, context);\n}\nfunction readContextForConsumer(consumer, context) {\n var value = context._currentValue;\n context = { context: context, memoizedValue: value, next: null };\n if (null === lastContextDependency) {\n if (null === consumer) throw Error(formatProdErrorMessage(308));\n lastContextDependency = context;\n consumer.dependencies = { lanes: 0, firstContext: context };\n consumer.flags |= 524288;\n } else lastContextDependency = lastContextDependency.next = context;\n return value;\n}\nvar AbortControllerLocal =\n \"undefined\" !== typeof AbortController\n ? AbortController\n : function () {\n var listeners = [],\n signal = (this.signal = {\n aborted: !1,\n addEventListener: function (type, listener) {\n listeners.push(listener);\n }\n });\n this.abort = function () {\n signal.aborted = !0;\n listeners.forEach(function (listener) {\n return listener();\n });\n };\n },\n scheduleCallback$2 = Scheduler.unstable_scheduleCallback,\n NormalPriority = Scheduler.unstable_NormalPriority,\n CacheContext = {\n $$typeof: REACT_CONTEXT_TYPE,\n Consumer: null,\n Provider: null,\n _currentValue: null,\n _currentValue2: null,\n _threadCount: 0\n };\nfunction createCache() {\n return {\n controller: new AbortControllerLocal(),\n data: new Map(),\n refCount: 0\n };\n}\nfunction releaseCache(cache) {\n cache.refCount--;\n 0 === cache.refCount &&\n scheduleCallback$2(NormalPriority, function () {\n cache.controller.abort();\n });\n}\nvar currentEntangledListeners = null,\n currentEntangledPendingCount = 0,\n currentEntangledLane = 0,\n currentEntangledActionThenable = null;\nfunction entangleAsyncAction(transition, thenable) {\n if (null === currentEntangledListeners) {\n var entangledListeners = (currentEntangledListeners = []);\n currentEntangledPendingCount = 0;\n currentEntangledLane = requestTransitionLane();\n currentEntangledActionThenable = {\n status: \"pending\",\n value: void 0,\n then: function (resolve) {\n entangledListeners.push(resolve);\n }\n };\n }\n currentEntangledPendingCount++;\n thenable.then(pingEngtangledActionScope, pingEngtangledActionScope);\n return thenable;\n}\nfunction pingEngtangledActionScope() {\n if (\n 0 === --currentEntangledPendingCount &&\n null !== currentEntangledListeners\n ) {\n null !== currentEntangledActionThenable &&\n (currentEntangledActionThenable.status = \"fulfilled\");\n var listeners = currentEntangledListeners;\n currentEntangledListeners = null;\n currentEntangledLane = 0;\n currentEntangledActionThenable = null;\n for (var i = 0; i < listeners.length; i++) (0, listeners[i])();\n }\n}\nfunction chainThenableValue(thenable, result) {\n var listeners = [],\n thenableWithOverride = {\n status: \"pending\",\n value: null,\n reason: null,\n then: function (resolve) {\n listeners.push(resolve);\n }\n };\n thenable.then(\n function () {\n thenableWithOverride.status = \"fulfilled\";\n thenableWithOverride.value = result;\n for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result);\n },\n function (error) {\n thenableWithOverride.status = \"rejected\";\n thenableWithOverride.reason = error;\n for (error = 0; error < listeners.length; error++)\n (0, listeners[error])(void 0);\n }\n );\n return thenableWithOverride;\n}\nvar prevOnStartTransitionFinish = ReactSharedInternals.S;\nReactSharedInternals.S = function (transition, returnValue) {\n globalMostRecentTransitionTime = now();\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n entangleAsyncAction(transition, returnValue);\n null !== prevOnStartTransitionFinish &&\n prevOnStartTransitionFinish(transition, returnValue);\n};\nvar resumedCache = createCursor(null);\nfunction peekCacheFromPool() {\n var cacheResumedFromPreviousRender = resumedCache.current;\n return null !== cacheResumedFromPreviousRender\n ? cacheResumedFromPreviousRender\n : workInProgressRoot.pooledCache;\n}\nfunction pushTransition(offscreenWorkInProgress, prevCachePool) {\n null === prevCachePool\n ? push(resumedCache, resumedCache.current)\n : push(resumedCache, prevCachePool.pool);\n}\nfunction getSuspendedCache() {\n var cacheFromPool = peekCacheFromPool();\n return null === cacheFromPool\n ? null\n : { parent: CacheContext._currentValue, pool: cacheFromPool };\n}\nvar SuspenseException = Error(formatProdErrorMessage(460)),\n SuspenseyCommitException = Error(formatProdErrorMessage(474)),\n SuspenseActionException = Error(formatProdErrorMessage(542)),\n noopSuspenseyCommitThenable = { then: function () {} };\nfunction isThenableResolved(thenable) {\n thenable = thenable.status;\n return \"fulfilled\" === thenable || \"rejected\" === thenable;\n}\nfunction trackUsedThenable(thenableState, thenable, index) {\n index = thenableState[index];\n void 0 === index\n ? thenableState.push(thenable)\n : index !== thenable && (thenable.then(noop$1, noop$1), (thenable = index));\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw (\n ((thenableState = thenable.reason),\n checkIfUseWrappedInAsyncCatch(thenableState),\n thenableState)\n );\n default:\n if (\"string\" === typeof thenable.status) thenable.then(noop$1, noop$1);\n else {\n thenableState = workInProgressRoot;\n if (null !== thenableState && 100 < thenableState.shellSuspendCounter)\n throw Error(formatProdErrorMessage(482));\n thenableState = thenable;\n thenableState.status = \"pending\";\n thenableState.then(\n function (fulfilledValue) {\n if (\"pending\" === thenable.status) {\n var fulfilledThenable = thenable;\n fulfilledThenable.status = \"fulfilled\";\n fulfilledThenable.value = fulfilledValue;\n }\n },\n function (error) {\n if (\"pending\" === thenable.status) {\n var rejectedThenable = thenable;\n rejectedThenable.status = \"rejected\";\n rejectedThenable.reason = error;\n }\n }\n );\n }\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw (\n ((thenableState = thenable.reason),\n checkIfUseWrappedInAsyncCatch(thenableState),\n thenableState)\n );\n }\n suspendedThenable = thenable;\n throw SuspenseException;\n }\n}\nfunction resolveLazy(lazyType) {\n try {\n var init = lazyType._init;\n return init(lazyType._payload);\n } catch (x) {\n if (null !== x && \"object\" === typeof x && \"function\" === typeof x.then)\n throw ((suspendedThenable = x), SuspenseException);\n throw x;\n }\n}\nvar suspendedThenable = null;\nfunction getSuspendedThenable() {\n if (null === suspendedThenable) throw Error(formatProdErrorMessage(459));\n var thenable = suspendedThenable;\n suspendedThenable = null;\n return thenable;\n}\nfunction checkIfUseWrappedInAsyncCatch(rejectedReason) {\n if (\n rejectedReason === SuspenseException ||\n rejectedReason === SuspenseActionException\n )\n throw Error(formatProdErrorMessage(483));\n}\nvar thenableState$1 = null,\n thenableIndexCounter$1 = 0;\nfunction unwrapThenable(thenable) {\n var index = thenableIndexCounter$1;\n thenableIndexCounter$1 += 1;\n null === thenableState$1 && (thenableState$1 = []);\n return trackUsedThenable(thenableState$1, thenable, index);\n}\nfunction coerceRef(workInProgress, element) {\n element = element.props.ref;\n workInProgress.ref = void 0 !== element ? element : null;\n}\nfunction throwOnInvalidObjectTypeImpl(returnFiber, newChild) {\n if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE)\n throw Error(formatProdErrorMessage(525));\n returnFiber = Object.prototype.toString.call(newChild);\n throw Error(\n formatProdErrorMessage(\n 31,\n \"[object Object]\" === returnFiber\n ? \"object with keys {\" + Object.keys(newChild).join(\", \") + \"}\"\n : returnFiber\n )\n );\n}\nfunction createChildReconciler(shouldTrackSideEffects) {\n function deleteChild(returnFiber, childToDelete) {\n if (shouldTrackSideEffects) {\n var deletions = returnFiber.deletions;\n null === deletions\n ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16))\n : deletions.push(childToDelete);\n }\n }\n function deleteRemainingChildren(returnFiber, currentFirstChild) {\n if (!shouldTrackSideEffects) return null;\n for (; null !== currentFirstChild; )\n deleteChild(returnFiber, currentFirstChild),\n (currentFirstChild = currentFirstChild.sibling);\n return null;\n }\n function mapRemainingChildren(currentFirstChild) {\n for (var existingChildren = new Map(); null !== currentFirstChild; )\n null !== currentFirstChild.key\n ? existingChildren.set(currentFirstChild.key, currentFirstChild)\n : existingChildren.set(currentFirstChild.index, currentFirstChild),\n (currentFirstChild = currentFirstChild.sibling);\n return existingChildren;\n }\n function useFiber(fiber, pendingProps) {\n fiber = createWorkInProgress(fiber, pendingProps);\n fiber.index = 0;\n fiber.sibling = null;\n return fiber;\n }\n function placeChild(newFiber, lastPlacedIndex, newIndex) {\n newFiber.index = newIndex;\n if (!shouldTrackSideEffects)\n return (newFiber.flags |= 1048576), lastPlacedIndex;\n newIndex = newFiber.alternate;\n if (null !== newIndex)\n return (\n (newIndex = newIndex.index),\n newIndex < lastPlacedIndex\n ? ((newFiber.flags |= 67108866), lastPlacedIndex)\n : newIndex\n );\n newFiber.flags |= 67108866;\n return lastPlacedIndex;\n }\n function placeSingleChild(newFiber) {\n shouldTrackSideEffects &&\n null === newFiber.alternate &&\n (newFiber.flags |= 67108866);\n return newFiber;\n }\n function updateTextNode(returnFiber, current, textContent, lanes) {\n if (null === current || 6 !== current.tag)\n return (\n (current = createFiberFromText(textContent, returnFiber.mode, lanes)),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, textContent);\n current.return = returnFiber;\n return current;\n }\n function updateElement(returnFiber, current, element, lanes) {\n var elementType = element.type;\n if (elementType === REACT_FRAGMENT_TYPE)\n return updateFragment(\n returnFiber,\n current,\n element.props.children,\n lanes,\n element.key\n );\n if (\n null !== current &&\n (current.elementType === elementType ||\n (\"object\" === typeof elementType &&\n null !== elementType &&\n elementType.$$typeof === REACT_LAZY_TYPE &&\n resolveLazy(elementType) === current.type))\n )\n return (\n (current = useFiber(current, element.props)),\n coerceRef(current, element),\n (current.return = returnFiber),\n current\n );\n current = createFiberFromTypeAndProps(\n element.type,\n element.key,\n element.props,\n null,\n returnFiber.mode,\n lanes\n );\n coerceRef(current, element);\n current.return = returnFiber;\n return current;\n }\n function updatePortal(returnFiber, current, portal, lanes) {\n if (\n null === current ||\n 4 !== current.tag ||\n current.stateNode.containerInfo !== portal.containerInfo ||\n current.stateNode.implementation !== portal.implementation\n )\n return (\n (current = createFiberFromPortal(portal, returnFiber.mode, lanes)),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, portal.children || []);\n current.return = returnFiber;\n return current;\n }\n function updateFragment(returnFiber, current, fragment, lanes, key) {\n if (null === current || 7 !== current.tag)\n return (\n (current = createFiberFromFragment(\n fragment,\n returnFiber.mode,\n lanes,\n key\n )),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, fragment);\n current.return = returnFiber;\n return current;\n }\n function createChild(returnFiber, newChild, lanes) {\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return (\n (newChild = createFiberFromText(\n \"\" + newChild,\n returnFiber.mode,\n lanes\n )),\n (newChild.return = returnFiber),\n newChild\n );\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return (\n (lanes = createFiberFromTypeAndProps(\n newChild.type,\n newChild.key,\n newChild.props,\n null,\n returnFiber.mode,\n lanes\n )),\n coerceRef(lanes, newChild),\n (lanes.return = returnFiber),\n lanes\n );\n case REACT_PORTAL_TYPE:\n return (\n (newChild = createFiberFromPortal(\n newChild,\n returnFiber.mode,\n lanes\n )),\n (newChild.return = returnFiber),\n newChild\n );\n case REACT_LAZY_TYPE:\n return (\n (newChild = resolveLazy(newChild)),\n createChild(returnFiber, newChild, lanes)\n );\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return (\n (newChild = createFiberFromFragment(\n newChild,\n returnFiber.mode,\n lanes,\n null\n )),\n (newChild.return = returnFiber),\n newChild\n );\n if (\"function\" === typeof newChild.then)\n return createChild(returnFiber, unwrapThenable(newChild), lanes);\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return createChild(\n returnFiber,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectTypeImpl(returnFiber, newChild);\n }\n return null;\n }\n function updateSlot(returnFiber, oldFiber, newChild, lanes) {\n var key = null !== oldFiber ? oldFiber.key : null;\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return null !== key\n ? null\n : updateTextNode(returnFiber, oldFiber, \"\" + newChild, lanes);\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return newChild.key === key\n ? updateElement(returnFiber, oldFiber, newChild, lanes)\n : null;\n case REACT_PORTAL_TYPE:\n return newChild.key === key\n ? updatePortal(returnFiber, oldFiber, newChild, lanes)\n : null;\n case REACT_LAZY_TYPE:\n return (\n (newChild = resolveLazy(newChild)),\n updateSlot(returnFiber, oldFiber, newChild, lanes)\n );\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return null !== key\n ? null\n : updateFragment(returnFiber, oldFiber, newChild, lanes, null);\n if (\"function\" === typeof newChild.then)\n return updateSlot(\n returnFiber,\n oldFiber,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return updateSlot(\n returnFiber,\n oldFiber,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectTypeImpl(returnFiber, newChild);\n }\n return null;\n }\n function updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n newChild,\n lanes\n ) {\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return (\n (existingChildren = existingChildren.get(newIdx) || null),\n updateTextNode(returnFiber, existingChildren, \"\" + newChild, lanes)\n );\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return (\n (existingChildren =\n existingChildren.get(\n null === newChild.key ? newIdx : newChild.key\n ) || null),\n updateElement(returnFiber, existingChildren, newChild, lanes)\n );\n case REACT_PORTAL_TYPE:\n return (\n (existingChildren =\n existingChildren.get(\n null === newChild.key ? newIdx : newChild.key\n ) || null),\n updatePortal(returnFiber, existingChildren, newChild, lanes)\n );\n case REACT_LAZY_TYPE:\n return (\n (newChild = resolveLazy(newChild)),\n updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n newChild,\n lanes\n )\n );\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return (\n (existingChildren = existingChildren.get(newIdx) || null),\n updateFragment(returnFiber, existingChildren, newChild, lanes, null)\n );\n if (\"function\" === typeof newChild.then)\n return updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectTypeImpl(returnFiber, newChild);\n }\n return null;\n }\n function reconcileChildrenArray(\n returnFiber,\n currentFirstChild,\n newChildren,\n lanes\n ) {\n for (\n var resultingFirstChild = null,\n previousNewFiber = null,\n oldFiber = currentFirstChild,\n newIdx = (currentFirstChild = 0),\n nextOldFiber = null;\n null !== oldFiber && newIdx < newChildren.length;\n newIdx++\n ) {\n oldFiber.index > newIdx\n ? ((nextOldFiber = oldFiber), (oldFiber = null))\n : (nextOldFiber = oldFiber.sibling);\n var newFiber = updateSlot(\n returnFiber,\n oldFiber,\n newChildren[newIdx],\n lanes\n );\n if (null === newFiber) {\n null === oldFiber && (oldFiber = nextOldFiber);\n break;\n }\n shouldTrackSideEffects &&\n oldFiber &&\n null === newFiber.alternate &&\n deleteChild(returnFiber, oldFiber);\n currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx);\n null === previousNewFiber\n ? (resultingFirstChild = newFiber)\n : (previousNewFiber.sibling = newFiber);\n previousNewFiber = newFiber;\n oldFiber = nextOldFiber;\n }\n if (newIdx === newChildren.length)\n return (\n deleteRemainingChildren(returnFiber, oldFiber),\n isHydrating && pushTreeFork(returnFiber, newIdx),\n resultingFirstChild\n );\n if (null === oldFiber) {\n for (; newIdx < newChildren.length; newIdx++)\n (oldFiber = createChild(returnFiber, newChildren[newIdx], lanes)),\n null !== oldFiber &&\n ((currentFirstChild = placeChild(\n oldFiber,\n currentFirstChild,\n newIdx\n )),\n null === previousNewFiber\n ? (resultingFirstChild = oldFiber)\n : (previousNewFiber.sibling = oldFiber),\n (previousNewFiber = oldFiber));\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n for (\n oldFiber = mapRemainingChildren(oldFiber);\n newIdx < newChildren.length;\n newIdx++\n )\n (nextOldFiber = updateFromMap(\n oldFiber,\n returnFiber,\n newIdx,\n newChildren[newIdx],\n lanes\n )),\n null !== nextOldFiber &&\n (shouldTrackSideEffects &&\n null !== nextOldFiber.alternate &&\n oldFiber.delete(\n null === nextOldFiber.key ? newIdx : nextOldFiber.key\n ),\n (currentFirstChild = placeChild(\n nextOldFiber,\n currentFirstChild,\n newIdx\n )),\n null === previousNewFiber\n ? (resultingFirstChild = nextOldFiber)\n : (previousNewFiber.sibling = nextOldFiber),\n (previousNewFiber = nextOldFiber));\n shouldTrackSideEffects &&\n oldFiber.forEach(function (child) {\n return deleteChild(returnFiber, child);\n });\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n function reconcileChildrenIterator(\n returnFiber,\n currentFirstChild,\n newChildren,\n lanes\n ) {\n if (null == newChildren) throw Error(formatProdErrorMessage(151));\n for (\n var resultingFirstChild = null,\n previousNewFiber = null,\n oldFiber = currentFirstChild,\n newIdx = (currentFirstChild = 0),\n nextOldFiber = null,\n step = newChildren.next();\n null !== oldFiber && !step.done;\n newIdx++, step = newChildren.next()\n ) {\n oldFiber.index > newIdx\n ? ((nextOldFiber = oldFiber), (oldFiber = null))\n : (nextOldFiber = oldFiber.sibling);\n var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);\n if (null === newFiber) {\n null === oldFiber && (oldFiber = nextOldFiber);\n break;\n }\n shouldTrackSideEffects &&\n oldFiber &&\n null === newFiber.alternate &&\n deleteChild(returnFiber, oldFiber);\n currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx);\n null === previousNewFiber\n ? (resultingFirstChild = newFiber)\n : (previousNewFiber.sibling = newFiber);\n previousNewFiber = newFiber;\n oldFiber = nextOldFiber;\n }\n if (step.done)\n return (\n deleteRemainingChildren(returnFiber, oldFiber),\n isHydrating && pushTreeFork(returnFiber, newIdx),\n resultingFirstChild\n );\n if (null === oldFiber) {\n for (; !step.done; newIdx++, step = newChildren.next())\n (step = createChild(returnFiber, step.value, lanes)),\n null !== step &&\n ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)),\n null === previousNewFiber\n ? (resultingFirstChild = step)\n : (previousNewFiber.sibling = step),\n (previousNewFiber = step));\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n for (\n oldFiber = mapRemainingChildren(oldFiber);\n !step.done;\n newIdx++, step = newChildren.next()\n )\n (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)),\n null !== step &&\n (shouldTrackSideEffects &&\n null !== step.alternate &&\n oldFiber.delete(null === step.key ? newIdx : step.key),\n (currentFirstChild = placeChild(step, currentFirstChild, newIdx)),\n null === previousNewFiber\n ? (resultingFirstChild = step)\n : (previousNewFiber.sibling = step),\n (previousNewFiber = step));\n shouldTrackSideEffects &&\n oldFiber.forEach(function (child) {\n return deleteChild(returnFiber, child);\n });\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n function reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n ) {\n \"object\" === typeof newChild &&\n null !== newChild &&\n newChild.type === REACT_FRAGMENT_TYPE &&\n null === newChild.key &&\n (newChild = newChild.props.children);\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n a: {\n for (var key = newChild.key; null !== currentFirstChild; ) {\n if (currentFirstChild.key === key) {\n key = newChild.type;\n if (key === REACT_FRAGMENT_TYPE) {\n if (7 === currentFirstChild.tag) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(\n currentFirstChild,\n newChild.props.children\n );\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n }\n } else if (\n currentFirstChild.elementType === key ||\n (\"object\" === typeof key &&\n null !== key &&\n key.$$typeof === REACT_LAZY_TYPE &&\n resolveLazy(key) === currentFirstChild.type)\n ) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(currentFirstChild, newChild.props);\n coerceRef(lanes, newChild);\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n }\n deleteRemainingChildren(returnFiber, currentFirstChild);\n break;\n } else deleteChild(returnFiber, currentFirstChild);\n currentFirstChild = currentFirstChild.sibling;\n }\n newChild.type === REACT_FRAGMENT_TYPE\n ? ((lanes = createFiberFromFragment(\n newChild.props.children,\n returnFiber.mode,\n lanes,\n newChild.key\n )),\n (lanes.return = returnFiber),\n (returnFiber = lanes))\n : ((lanes = createFiberFromTypeAndProps(\n newChild.type,\n newChild.key,\n newChild.props,\n null,\n returnFiber.mode,\n lanes\n )),\n coerceRef(lanes, newChild),\n (lanes.return = returnFiber),\n (returnFiber = lanes));\n }\n return placeSingleChild(returnFiber);\n case REACT_PORTAL_TYPE:\n a: {\n for (key = newChild.key; null !== currentFirstChild; ) {\n if (currentFirstChild.key === key)\n if (\n 4 === currentFirstChild.tag &&\n currentFirstChild.stateNode.containerInfo ===\n newChild.containerInfo &&\n currentFirstChild.stateNode.implementation ===\n newChild.implementation\n ) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(currentFirstChild, newChild.children || []);\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n } else {\n deleteRemainingChildren(returnFiber, currentFirstChild);\n break;\n }\n else deleteChild(returnFiber, currentFirstChild);\n currentFirstChild = currentFirstChild.sibling;\n }\n lanes = createFiberFromPortal(newChild, returnFiber.mode, lanes);\n lanes.return = returnFiber;\n returnFiber = lanes;\n }\n return placeSingleChild(returnFiber);\n case REACT_LAZY_TYPE:\n return (\n (newChild = resolveLazy(newChild)),\n reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n )\n );\n }\n if (isArrayImpl(newChild))\n return reconcileChildrenArray(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n if (getIteratorFn(newChild)) {\n key = getIteratorFn(newChild);\n if (\"function\" !== typeof key) throw Error(formatProdErrorMessage(150));\n newChild = key.call(newChild);\n return reconcileChildrenIterator(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n }\n if (\"function\" === typeof newChild.then)\n return reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectTypeImpl(returnFiber, newChild);\n }\n return (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n ? ((newChild = \"\" + newChild),\n null !== currentFirstChild && 6 === currentFirstChild.tag\n ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling),\n (lanes = useFiber(currentFirstChild, newChild)),\n (lanes.return = returnFiber),\n (returnFiber = lanes))\n : (deleteRemainingChildren(returnFiber, currentFirstChild),\n (lanes = createFiberFromText(newChild, returnFiber.mode, lanes)),\n (lanes.return = returnFiber),\n (returnFiber = lanes)),\n placeSingleChild(returnFiber))\n : deleteRemainingChildren(returnFiber, currentFirstChild);\n }\n return function (returnFiber, currentFirstChild, newChild, lanes) {\n try {\n thenableIndexCounter$1 = 0;\n var firstChildFiber = reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n thenableState$1 = null;\n return firstChildFiber;\n } catch (x) {\n if (x === SuspenseException || x === SuspenseActionException) throw x;\n var fiber = createFiberImplClass(29, x, null, returnFiber.mode);\n fiber.lanes = lanes;\n fiber.return = returnFiber;\n return fiber;\n } finally {\n }\n };\n}\nvar reconcileChildFibers = createChildReconciler(!0),\n mountChildFibers = createChildReconciler(!1),\n hasForceUpdate = !1;\nfunction initializeUpdateQueue(fiber) {\n fiber.updateQueue = {\n baseState: fiber.memoizedState,\n firstBaseUpdate: null,\n lastBaseUpdate: null,\n shared: { pending: null, lanes: 0, hiddenCallbacks: null },\n callbacks: null\n };\n}\nfunction cloneUpdateQueue(current, workInProgress) {\n current = current.updateQueue;\n workInProgress.updateQueue === current &&\n (workInProgress.updateQueue = {\n baseState: current.baseState,\n firstBaseUpdate: current.firstBaseUpdate,\n lastBaseUpdate: current.lastBaseUpdate,\n shared: current.shared,\n callbacks: null\n });\n}\nfunction createUpdate(lane) {\n return { lane: lane, tag: 0, payload: null, callback: null, next: null };\n}\nfunction enqueueUpdate(fiber, update, lane) {\n var updateQueue = fiber.updateQueue;\n if (null === updateQueue) return null;\n updateQueue = updateQueue.shared;\n if (0 !== (executionContext & 2)) {\n var pending = updateQueue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n updateQueue.pending = update;\n update = getRootForUpdatedFiber(fiber);\n markUpdateLaneFromFiberToRoot(fiber, null, lane);\n return update;\n }\n enqueueUpdate$1(fiber, updateQueue, update, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction entangleTransitions(root, fiber, lane) {\n fiber = fiber.updateQueue;\n if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 4194048))) {\n var queueLanes = fiber.lanes;\n queueLanes &= root.pendingLanes;\n lane |= queueLanes;\n fiber.lanes = lane;\n markRootEntangled(root, lane);\n }\n}\nfunction enqueueCapturedUpdate(workInProgress, capturedUpdate) {\n var queue = workInProgress.updateQueue,\n current = workInProgress.alternate;\n if (\n null !== current &&\n ((current = current.updateQueue), queue === current)\n ) {\n var newFirst = null,\n newLast = null;\n queue = queue.firstBaseUpdate;\n if (null !== queue) {\n do {\n var clone = {\n lane: queue.lane,\n tag: queue.tag,\n payload: queue.payload,\n callback: null,\n next: null\n };\n null === newLast\n ? (newFirst = newLast = clone)\n : (newLast = newLast.next = clone);\n queue = queue.next;\n } while (null !== queue);\n null === newLast\n ? (newFirst = newLast = capturedUpdate)\n : (newLast = newLast.next = capturedUpdate);\n } else newFirst = newLast = capturedUpdate;\n queue = {\n baseState: current.baseState,\n firstBaseUpdate: newFirst,\n lastBaseUpdate: newLast,\n shared: current.shared,\n callbacks: current.callbacks\n };\n workInProgress.updateQueue = queue;\n return;\n }\n workInProgress = queue.lastBaseUpdate;\n null === workInProgress\n ? (queue.firstBaseUpdate = capturedUpdate)\n : (workInProgress.next = capturedUpdate);\n queue.lastBaseUpdate = capturedUpdate;\n}\nvar didReadFromEntangledAsyncAction = !1;\nfunction suspendIfUpdateReadFromEntangledAsyncAction() {\n if (didReadFromEntangledAsyncAction) {\n var entangledActionThenable = currentEntangledActionThenable;\n if (null !== entangledActionThenable) throw entangledActionThenable;\n }\n}\nfunction processUpdateQueue(\n workInProgress$jscomp$0,\n props,\n instance$jscomp$0,\n renderLanes\n) {\n didReadFromEntangledAsyncAction = !1;\n var queue = workInProgress$jscomp$0.updateQueue;\n hasForceUpdate = !1;\n var firstBaseUpdate = queue.firstBaseUpdate,\n lastBaseUpdate = queue.lastBaseUpdate,\n pendingQueue = queue.shared.pending;\n if (null !== pendingQueue) {\n queue.shared.pending = null;\n var lastPendingUpdate = pendingQueue,\n firstPendingUpdate = lastPendingUpdate.next;\n lastPendingUpdate.next = null;\n null === lastBaseUpdate\n ? (firstBaseUpdate = firstPendingUpdate)\n : (lastBaseUpdate.next = firstPendingUpdate);\n lastBaseUpdate = lastPendingUpdate;\n var current = workInProgress$jscomp$0.alternate;\n null !== current &&\n ((current = current.updateQueue),\n (pendingQueue = current.lastBaseUpdate),\n pendingQueue !== lastBaseUpdate &&\n (null === pendingQueue\n ? (current.firstBaseUpdate = firstPendingUpdate)\n : (pendingQueue.next = firstPendingUpdate),\n (current.lastBaseUpdate = lastPendingUpdate)));\n }\n if (null !== firstBaseUpdate) {\n var newState = queue.baseState;\n lastBaseUpdate = 0;\n current = firstPendingUpdate = lastPendingUpdate = null;\n pendingQueue = firstBaseUpdate;\n do {\n var updateLane = pendingQueue.lane & -536870913,\n isHiddenUpdate = updateLane !== pendingQueue.lane;\n if (\n isHiddenUpdate\n ? (workInProgressRootRenderLanes & updateLane) === updateLane\n : (renderLanes & updateLane) === updateLane\n ) {\n 0 !== updateLane &&\n updateLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction = !0);\n null !== current &&\n (current = current.next =\n {\n lane: 0,\n tag: pendingQueue.tag,\n payload: pendingQueue.payload,\n callback: null,\n next: null\n });\n a: {\n var workInProgress = workInProgress$jscomp$0,\n update = pendingQueue;\n updateLane = props;\n var instance = instance$jscomp$0;\n switch (update.tag) {\n case 1:\n workInProgress = update.payload;\n if (\"function\" === typeof workInProgress) {\n newState = workInProgress.call(instance, newState, updateLane);\n break a;\n }\n newState = workInProgress;\n break a;\n case 3:\n workInProgress.flags = (workInProgress.flags & -65537) | 128;\n case 0:\n workInProgress = update.payload;\n updateLane =\n \"function\" === typeof workInProgress\n ? workInProgress.call(instance, newState, updateLane)\n : workInProgress;\n if (null === updateLane || void 0 === updateLane) break a;\n newState = assign({}, newState, updateLane);\n break a;\n case 2:\n hasForceUpdate = !0;\n }\n }\n updateLane = pendingQueue.callback;\n null !== updateLane &&\n ((workInProgress$jscomp$0.flags |= 64),\n isHiddenUpdate && (workInProgress$jscomp$0.flags |= 8192),\n (isHiddenUpdate = queue.callbacks),\n null === isHiddenUpdate\n ? (queue.callbacks = [updateLane])\n : isHiddenUpdate.push(updateLane));\n } else\n (isHiddenUpdate = {\n lane: updateLane,\n tag: pendingQueue.tag,\n payload: pendingQueue.payload,\n callback: pendingQueue.callback,\n next: null\n }),\n null === current\n ? ((firstPendingUpdate = current = isHiddenUpdate),\n (lastPendingUpdate = newState))\n : (current = current.next = isHiddenUpdate),\n (lastBaseUpdate |= updateLane);\n pendingQueue = pendingQueue.next;\n if (null === pendingQueue)\n if (((pendingQueue = queue.shared.pending), null === pendingQueue))\n break;\n else\n (isHiddenUpdate = pendingQueue),\n (pendingQueue = isHiddenUpdate.next),\n (isHiddenUpdate.next = null),\n (queue.lastBaseUpdate = isHiddenUpdate),\n (queue.shared.pending = null);\n } while (1);\n null === current && (lastPendingUpdate = newState);\n queue.baseState = lastPendingUpdate;\n queue.firstBaseUpdate = firstPendingUpdate;\n queue.lastBaseUpdate = current;\n null === firstBaseUpdate && (queue.shared.lanes = 0);\n workInProgressRootSkippedLanes |= lastBaseUpdate;\n workInProgress$jscomp$0.lanes = lastBaseUpdate;\n workInProgress$jscomp$0.memoizedState = newState;\n }\n}\nfunction callCallback(callback, context) {\n if (\"function\" !== typeof callback)\n throw Error(formatProdErrorMessage(191, callback));\n callback.call(context);\n}\nfunction commitCallbacks(updateQueue, context) {\n var callbacks = updateQueue.callbacks;\n if (null !== callbacks)\n for (\n updateQueue.callbacks = null, updateQueue = 0;\n updateQueue < callbacks.length;\n updateQueue++\n )\n callCallback(callbacks[updateQueue], context);\n}\nvar currentTreeHiddenStackCursor = createCursor(null),\n prevEntangledRenderLanesCursor = createCursor(0);\nfunction pushHiddenContext(fiber, context) {\n fiber = entangledRenderLanes;\n push(prevEntangledRenderLanesCursor, fiber);\n push(currentTreeHiddenStackCursor, context);\n entangledRenderLanes = fiber | context.baseLanes;\n}\nfunction reuseHiddenContextOnStack() {\n push(prevEntangledRenderLanesCursor, entangledRenderLanes);\n push(currentTreeHiddenStackCursor, currentTreeHiddenStackCursor.current);\n}\nfunction popHiddenContext() {\n entangledRenderLanes = prevEntangledRenderLanesCursor.current;\n pop(currentTreeHiddenStackCursor);\n pop(prevEntangledRenderLanesCursor);\n}\nvar suspenseHandlerStackCursor = createCursor(null),\n shellBoundary = null;\nfunction pushPrimaryTreeSuspenseHandler(handler) {\n var current = handler.alternate;\n push(suspenseStackCursor, suspenseStackCursor.current & 1);\n push(suspenseHandlerStackCursor, handler);\n null === shellBoundary &&\n (null === current || null !== currentTreeHiddenStackCursor.current\n ? (shellBoundary = handler)\n : null !== current.memoizedState && (shellBoundary = handler));\n}\nfunction pushDehydratedActivitySuspenseHandler(fiber) {\n push(suspenseStackCursor, suspenseStackCursor.current);\n push(suspenseHandlerStackCursor, fiber);\n null === shellBoundary && (shellBoundary = fiber);\n}\nfunction pushOffscreenSuspenseHandler(fiber) {\n 22 === fiber.tag\n ? (push(suspenseStackCursor, suspenseStackCursor.current),\n push(suspenseHandlerStackCursor, fiber),\n null === shellBoundary && (shellBoundary = fiber))\n : reuseSuspenseHandlerOnStack(fiber);\n}\nfunction reuseSuspenseHandlerOnStack() {\n push(suspenseStackCursor, suspenseStackCursor.current);\n push(suspenseHandlerStackCursor, suspenseHandlerStackCursor.current);\n}\nfunction popSuspenseHandler(fiber) {\n pop(suspenseHandlerStackCursor);\n shellBoundary === fiber && (shellBoundary = null);\n pop(suspenseStackCursor);\n}\nvar suspenseStackCursor = createCursor(0);\nfunction findFirstSuspended(row) {\n for (var node = row; null !== node; ) {\n if (13 === node.tag) {\n var state = node.memoizedState;\n if (\n null !== state &&\n ((state = state.dehydrated),\n null === state ||\n isSuspenseInstancePending(state) ||\n isSuspenseInstanceFallback(state))\n )\n return node;\n } else if (\n 19 === node.tag &&\n (\"forwards\" === node.memoizedProps.revealOrder ||\n \"backwards\" === node.memoizedProps.revealOrder ||\n \"unstable_legacy-backwards\" === node.memoizedProps.revealOrder ||\n \"together\" === node.memoizedProps.revealOrder)\n ) {\n if (0 !== (node.flags & 128)) return node;\n } else if (null !== node.child) {\n node.child.return = node;\n node = node.child;\n continue;\n }\n if (node === row) break;\n for (; null === node.sibling; ) {\n if (null === node.return || node.return === row) return null;\n node = node.return;\n }\n node.sibling.return = node.return;\n node = node.sibling;\n }\n return null;\n}\nvar renderLanes = 0,\n currentlyRenderingFiber = null,\n currentHook = null,\n workInProgressHook = null,\n didScheduleRenderPhaseUpdate = !1,\n didScheduleRenderPhaseUpdateDuringThisPass = !1,\n shouldDoubleInvokeUserFnsInHooksDEV = !1,\n localIdCounter = 0,\n thenableIndexCounter = 0,\n thenableState = null,\n globalClientIdCounter = 0;\nfunction throwInvalidHookError() {\n throw Error(formatProdErrorMessage(321));\n}\nfunction areHookInputsEqual(nextDeps, prevDeps) {\n if (null === prevDeps) return !1;\n for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++)\n if (!objectIs(nextDeps[i], prevDeps[i])) return !1;\n return !0;\n}\nfunction renderWithHooks(\n current,\n workInProgress,\n Component,\n props,\n secondArg,\n nextRenderLanes\n) {\n renderLanes = nextRenderLanes;\n currentlyRenderingFiber = workInProgress;\n workInProgress.memoizedState = null;\n workInProgress.updateQueue = null;\n workInProgress.lanes = 0;\n ReactSharedInternals.H =\n null === current || null === current.memoizedState\n ? HooksDispatcherOnMount\n : HooksDispatcherOnUpdate;\n shouldDoubleInvokeUserFnsInHooksDEV = !1;\n nextRenderLanes = Component(props, secondArg);\n shouldDoubleInvokeUserFnsInHooksDEV = !1;\n didScheduleRenderPhaseUpdateDuringThisPass &&\n (nextRenderLanes = renderWithHooksAgain(\n workInProgress,\n Component,\n props,\n secondArg\n ));\n finishRenderingHooks(current);\n return nextRenderLanes;\n}\nfunction finishRenderingHooks(current) {\n ReactSharedInternals.H = ContextOnlyDispatcher;\n var didRenderTooFewHooks = null !== currentHook && null !== currentHook.next;\n renderLanes = 0;\n workInProgressHook = currentHook = currentlyRenderingFiber = null;\n didScheduleRenderPhaseUpdate = !1;\n thenableIndexCounter = 0;\n thenableState = null;\n if (didRenderTooFewHooks) throw Error(formatProdErrorMessage(300));\n null === current ||\n didReceiveUpdate ||\n ((current = current.dependencies),\n null !== current &&\n checkIfContextChanged(current) &&\n (didReceiveUpdate = !0));\n}\nfunction renderWithHooksAgain(workInProgress, Component, props, secondArg) {\n currentlyRenderingFiber = workInProgress;\n var numberOfReRenders = 0;\n do {\n didScheduleRenderPhaseUpdateDuringThisPass && (thenableState = null);\n thenableIndexCounter = 0;\n didScheduleRenderPhaseUpdateDuringThisPass = !1;\n if (25 <= numberOfReRenders) throw Error(formatProdErrorMessage(301));\n numberOfReRenders += 1;\n workInProgressHook = currentHook = null;\n if (null != workInProgress.updateQueue) {\n var children = workInProgress.updateQueue;\n children.lastEffect = null;\n children.events = null;\n children.stores = null;\n null != children.memoCache && (children.memoCache.index = 0);\n }\n ReactSharedInternals.H = HooksDispatcherOnRerender;\n children = Component(props, secondArg);\n } while (didScheduleRenderPhaseUpdateDuringThisPass);\n return children;\n}\nfunction TransitionAwareHostComponent() {\n var dispatcher = ReactSharedInternals.H,\n maybeThenable = dispatcher.useState()[0];\n maybeThenable =\n \"function\" === typeof maybeThenable.then\n ? useThenable(maybeThenable)\n : maybeThenable;\n dispatcher = dispatcher.useState()[0];\n (null !== currentHook ? currentHook.memoizedState : null) !== dispatcher &&\n (currentlyRenderingFiber.flags |= 1024);\n return maybeThenable;\n}\nfunction checkDidRenderIdHook() {\n var didRenderIdHook = 0 !== localIdCounter;\n localIdCounter = 0;\n return didRenderIdHook;\n}\nfunction bailoutHooks(current, workInProgress, lanes) {\n workInProgress.updateQueue = current.updateQueue;\n workInProgress.flags &= -2053;\n current.lanes &= ~lanes;\n}\nfunction resetHooksOnUnwind(workInProgress) {\n if (didScheduleRenderPhaseUpdate) {\n for (\n workInProgress = workInProgress.memoizedState;\n null !== workInProgress;\n\n ) {\n var queue = workInProgress.queue;\n null !== queue && (queue.pending = null);\n workInProgress = workInProgress.next;\n }\n didScheduleRenderPhaseUpdate = !1;\n }\n renderLanes = 0;\n workInProgressHook = currentHook = currentlyRenderingFiber = null;\n didScheduleRenderPhaseUpdateDuringThisPass = !1;\n thenableIndexCounter = localIdCounter = 0;\n thenableState = null;\n}\nfunction mountWorkInProgressHook() {\n var hook = {\n memoizedState: null,\n baseState: null,\n baseQueue: null,\n queue: null,\n next: null\n };\n null === workInProgressHook\n ? (currentlyRenderingFiber.memoizedState = workInProgressHook = hook)\n : (workInProgressHook = workInProgressHook.next = hook);\n return workInProgressHook;\n}\nfunction updateWorkInProgressHook() {\n if (null === currentHook) {\n var nextCurrentHook = currentlyRenderingFiber.alternate;\n nextCurrentHook =\n null !== nextCurrentHook ? nextCurrentHook.memoizedState : null;\n } else nextCurrentHook = currentHook.next;\n var nextWorkInProgressHook =\n null === workInProgressHook\n ? currentlyRenderingFiber.memoizedState\n : workInProgressHook.next;\n if (null !== nextWorkInProgressHook)\n (workInProgressHook = nextWorkInProgressHook),\n (currentHook = nextCurrentHook);\n else {\n if (null === nextCurrentHook) {\n if (null === currentlyRenderingFiber.alternate)\n throw Error(formatProdErrorMessage(467));\n throw Error(formatProdErrorMessage(310));\n }\n currentHook = nextCurrentHook;\n nextCurrentHook = {\n memoizedState: currentHook.memoizedState,\n baseState: currentHook.baseState,\n baseQueue: currentHook.baseQueue,\n queue: currentHook.queue,\n next: null\n };\n null === workInProgressHook\n ? (currentlyRenderingFiber.memoizedState = workInProgressHook =\n nextCurrentHook)\n : (workInProgressHook = workInProgressHook.next = nextCurrentHook);\n }\n return workInProgressHook;\n}\nfunction createFunctionComponentUpdateQueue() {\n return { lastEffect: null, events: null, stores: null, memoCache: null };\n}\nfunction useThenable(thenable) {\n var index = thenableIndexCounter;\n thenableIndexCounter += 1;\n null === thenableState && (thenableState = []);\n thenable = trackUsedThenable(thenableState, thenable, index);\n index = currentlyRenderingFiber;\n null ===\n (null === workInProgressHook\n ? index.memoizedState\n : workInProgressHook.next) &&\n ((index = index.alternate),\n (ReactSharedInternals.H =\n null === index || null === index.memoizedState\n ? HooksDispatcherOnMount\n : HooksDispatcherOnUpdate));\n return thenable;\n}\nfunction use(usable) {\n if (null !== usable && \"object\" === typeof usable) {\n if (\"function\" === typeof usable.then) return useThenable(usable);\n if (usable.$$typeof === REACT_CONTEXT_TYPE) return readContext(usable);\n }\n throw Error(formatProdErrorMessage(438, String(usable)));\n}\nfunction useMemoCache(size) {\n var memoCache = null,\n updateQueue = currentlyRenderingFiber.updateQueue;\n null !== updateQueue && (memoCache = updateQueue.memoCache);\n if (null == memoCache) {\n var current = currentlyRenderingFiber.alternate;\n null !== current &&\n ((current = current.updateQueue),\n null !== current &&\n ((current = current.memoCache),\n null != current &&\n (memoCache = {\n data: current.data.map(function (array) {\n return array.slice();\n }),\n index: 0\n })));\n }\n null == memoCache && (memoCache = { data: [], index: 0 });\n null === updateQueue &&\n ((updateQueue = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = updateQueue));\n updateQueue.memoCache = memoCache;\n updateQueue = memoCache.data[memoCache.index];\n if (void 0 === updateQueue)\n for (\n updateQueue = memoCache.data[memoCache.index] = Array(size), current = 0;\n current < size;\n current++\n )\n updateQueue[current] = REACT_MEMO_CACHE_SENTINEL;\n memoCache.index++;\n return updateQueue;\n}\nfunction basicStateReducer(state, action) {\n return \"function\" === typeof action ? action(state) : action;\n}\nfunction updateReducer(reducer) {\n var hook = updateWorkInProgressHook();\n return updateReducerImpl(hook, currentHook, reducer);\n}\nfunction updateReducerImpl(hook, current, reducer) {\n var queue = hook.queue;\n if (null === queue) throw Error(formatProdErrorMessage(311));\n queue.lastRenderedReducer = reducer;\n var baseQueue = hook.baseQueue,\n pendingQueue = queue.pending;\n if (null !== pendingQueue) {\n if (null !== baseQueue) {\n var baseFirst = baseQueue.next;\n baseQueue.next = pendingQueue.next;\n pendingQueue.next = baseFirst;\n }\n current.baseQueue = baseQueue = pendingQueue;\n queue.pending = null;\n }\n pendingQueue = hook.baseState;\n if (null === baseQueue) hook.memoizedState = pendingQueue;\n else {\n current = baseQueue.next;\n var newBaseQueueFirst = (baseFirst = null),\n newBaseQueueLast = null,\n update = current,\n didReadFromEntangledAsyncAction$60 = !1;\n do {\n var updateLane = update.lane & -536870913;\n if (\n updateLane !== update.lane\n ? (workInProgressRootRenderLanes & updateLane) === updateLane\n : (renderLanes & updateLane) === updateLane\n ) {\n var revertLane = update.revertLane;\n if (0 === revertLane)\n null !== newBaseQueueLast &&\n (newBaseQueueLast = newBaseQueueLast.next =\n {\n lane: 0,\n revertLane: 0,\n gesture: null,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n updateLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction$60 = !0);\n else if ((renderLanes & revertLane) === revertLane) {\n update = update.next;\n revertLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction$60 = !0);\n continue;\n } else\n (updateLane = {\n lane: 0,\n revertLane: update.revertLane,\n gesture: null,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n null === newBaseQueueLast\n ? ((newBaseQueueFirst = newBaseQueueLast = updateLane),\n (baseFirst = pendingQueue))\n : (newBaseQueueLast = newBaseQueueLast.next = updateLane),\n (currentlyRenderingFiber.lanes |= revertLane),\n (workInProgressRootSkippedLanes |= revertLane);\n updateLane = update.action;\n shouldDoubleInvokeUserFnsInHooksDEV &&\n reducer(pendingQueue, updateLane);\n pendingQueue = update.hasEagerState\n ? update.eagerState\n : reducer(pendingQueue, updateLane);\n } else\n (revertLane = {\n lane: updateLane,\n revertLane: update.revertLane,\n gesture: update.gesture,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n null === newBaseQueueLast\n ? ((newBaseQueueFirst = newBaseQueueLast = revertLane),\n (baseFirst = pendingQueue))\n : (newBaseQueueLast = newBaseQueueLast.next = revertLane),\n (currentlyRenderingFiber.lanes |= updateLane),\n (workInProgressRootSkippedLanes |= updateLane);\n update = update.next;\n } while (null !== update && update !== current);\n null === newBaseQueueLast\n ? (baseFirst = pendingQueue)\n : (newBaseQueueLast.next = newBaseQueueFirst);\n if (\n !objectIs(pendingQueue, hook.memoizedState) &&\n ((didReceiveUpdate = !0),\n didReadFromEntangledAsyncAction$60 &&\n ((reducer = currentEntangledActionThenable), null !== reducer))\n )\n throw reducer;\n hook.memoizedState = pendingQueue;\n hook.baseState = baseFirst;\n hook.baseQueue = newBaseQueueLast;\n queue.lastRenderedState = pendingQueue;\n }\n null === baseQueue && (queue.lanes = 0);\n return [hook.memoizedState, queue.dispatch];\n}\nfunction rerenderReducer(reducer) {\n var hook = updateWorkInProgressHook(),\n queue = hook.queue;\n if (null === queue) throw Error(formatProdErrorMessage(311));\n queue.lastRenderedReducer = reducer;\n var dispatch = queue.dispatch,\n lastRenderPhaseUpdate = queue.pending,\n newState = hook.memoizedState;\n if (null !== lastRenderPhaseUpdate) {\n queue.pending = null;\n var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next);\n do (newState = reducer(newState, update.action)), (update = update.next);\n while (update !== lastRenderPhaseUpdate);\n objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0);\n hook.memoizedState = newState;\n null === hook.baseQueue && (hook.baseState = newState);\n queue.lastRenderedState = newState;\n }\n return [newState, dispatch];\n}\nfunction updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {\n var fiber = currentlyRenderingFiber,\n hook = updateWorkInProgressHook(),\n isHydrating$jscomp$0 = isHydrating;\n if (isHydrating$jscomp$0) {\n if (void 0 === getServerSnapshot) throw Error(formatProdErrorMessage(407));\n getServerSnapshot = getServerSnapshot();\n } else getServerSnapshot = getSnapshot();\n var snapshotChanged = !objectIs(\n (currentHook || hook).memoizedState,\n getServerSnapshot\n );\n snapshotChanged &&\n ((hook.memoizedState = getServerSnapshot), (didReceiveUpdate = !0));\n hook = hook.queue;\n updateEffect(subscribeToStore.bind(null, fiber, hook, subscribe), [\n subscribe\n ]);\n if (\n hook.getSnapshot !== getSnapshot ||\n snapshotChanged ||\n (null !== workInProgressHook && workInProgressHook.memoizedState.tag & 1)\n ) {\n fiber.flags |= 2048;\n pushSimpleEffect(\n 9,\n { destroy: void 0 },\n updateStoreInstance.bind(\n null,\n fiber,\n hook,\n getServerSnapshot,\n getSnapshot\n ),\n null\n );\n if (null === workInProgressRoot) throw Error(formatProdErrorMessage(349));\n isHydrating$jscomp$0 ||\n 0 !== (renderLanes & 127) ||\n pushStoreConsistencyCheck(fiber, getSnapshot, getServerSnapshot);\n }\n return getServerSnapshot;\n}\nfunction pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {\n fiber.flags |= 16384;\n fiber = { getSnapshot: getSnapshot, value: renderedSnapshot };\n getSnapshot = currentlyRenderingFiber.updateQueue;\n null === getSnapshot\n ? ((getSnapshot = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = getSnapshot),\n (getSnapshot.stores = [fiber]))\n : ((renderedSnapshot = getSnapshot.stores),\n null === renderedSnapshot\n ? (getSnapshot.stores = [fiber])\n : renderedSnapshot.push(fiber));\n}\nfunction updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {\n inst.value = nextSnapshot;\n inst.getSnapshot = getSnapshot;\n checkIfSnapshotChanged(inst) && forceStoreRerender(fiber);\n}\nfunction subscribeToStore(fiber, inst, subscribe) {\n return subscribe(function () {\n checkIfSnapshotChanged(inst) && forceStoreRerender(fiber);\n });\n}\nfunction checkIfSnapshotChanged(inst) {\n var latestGetSnapshot = inst.getSnapshot;\n inst = inst.value;\n try {\n var nextValue = latestGetSnapshot();\n return !objectIs(inst, nextValue);\n } catch (error) {\n return !0;\n }\n}\nfunction forceStoreRerender(fiber) {\n var root = enqueueConcurrentRenderForLane(fiber, 2);\n null !== root && scheduleUpdateOnFiber(root, fiber, 2);\n}\nfunction mountStateImpl(initialState) {\n var hook = mountWorkInProgressHook();\n if (\"function\" === typeof initialState) {\n var initialStateInitializer = initialState;\n initialState = initialStateInitializer();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n initialStateInitializer();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n }\n hook.memoizedState = hook.baseState = initialState;\n hook.queue = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: initialState\n };\n return hook;\n}\nfunction updateOptimisticImpl(hook, current, passthrough, reducer) {\n hook.baseState = passthrough;\n return updateReducerImpl(\n hook,\n currentHook,\n \"function\" === typeof reducer ? reducer : basicStateReducer\n );\n}\nfunction dispatchActionState(\n fiber,\n actionQueue,\n setPendingState,\n setState,\n payload\n) {\n if (isRenderPhaseUpdate(fiber)) throw Error(formatProdErrorMessage(485));\n fiber = actionQueue.action;\n if (null !== fiber) {\n var actionNode = {\n payload: payload,\n action: fiber,\n next: null,\n isTransition: !0,\n status: \"pending\",\n value: null,\n reason: null,\n listeners: [],\n then: function (listener) {\n actionNode.listeners.push(listener);\n }\n };\n null !== ReactSharedInternals.T\n ? setPendingState(!0)\n : (actionNode.isTransition = !1);\n setState(actionNode);\n setPendingState = actionQueue.pending;\n null === setPendingState\n ? ((actionNode.next = actionQueue.pending = actionNode),\n runActionStateAction(actionQueue, actionNode))\n : ((actionNode.next = setPendingState.next),\n (actionQueue.pending = setPendingState.next = actionNode));\n }\n}\nfunction runActionStateAction(actionQueue, node) {\n var action = node.action,\n payload = node.payload,\n prevState = actionQueue.state;\n if (node.isTransition) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = action(prevState, payload),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n handleActionReturnValue(actionQueue, node, returnValue);\n } catch (error) {\n onActionError(actionQueue, node, error);\n } finally {\n null !== prevTransition &&\n null !== currentTransition.types &&\n (prevTransition.types = currentTransition.types),\n (ReactSharedInternals.T = prevTransition);\n }\n } else\n try {\n (prevTransition = action(prevState, payload)),\n handleActionReturnValue(actionQueue, node, prevTransition);\n } catch (error$66) {\n onActionError(actionQueue, node, error$66);\n }\n}\nfunction handleActionReturnValue(actionQueue, node, returnValue) {\n null !== returnValue &&\n \"object\" === typeof returnValue &&\n \"function\" === typeof returnValue.then\n ? returnValue.then(\n function (nextState) {\n onActionSuccess(actionQueue, node, nextState);\n },\n function (error) {\n return onActionError(actionQueue, node, error);\n }\n )\n : onActionSuccess(actionQueue, node, returnValue);\n}\nfunction onActionSuccess(actionQueue, actionNode, nextState) {\n actionNode.status = \"fulfilled\";\n actionNode.value = nextState;\n notifyActionListeners(actionNode);\n actionQueue.state = nextState;\n actionNode = actionQueue.pending;\n null !== actionNode &&\n ((nextState = actionNode.next),\n nextState === actionNode\n ? (actionQueue.pending = null)\n : ((nextState = nextState.next),\n (actionNode.next = nextState),\n runActionStateAction(actionQueue, nextState)));\n}\nfunction onActionError(actionQueue, actionNode, error) {\n var last = actionQueue.pending;\n actionQueue.pending = null;\n if (null !== last) {\n last = last.next;\n do\n (actionNode.status = \"rejected\"),\n (actionNode.reason = error),\n notifyActionListeners(actionNode),\n (actionNode = actionNode.next);\n while (actionNode !== last);\n }\n actionQueue.action = null;\n}\nfunction notifyActionListeners(actionNode) {\n actionNode = actionNode.listeners;\n for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])();\n}\nfunction actionStateReducer(oldState, newState) {\n return newState;\n}\nfunction mountActionState(action, initialStateProp) {\n if (isHydrating) {\n var ssrFormState = workInProgressRoot.formState;\n if (null !== ssrFormState) {\n a: {\n var JSCompiler_inline_result = currentlyRenderingFiber;\n if (isHydrating) {\n if (nextHydratableInstance) {\n b: {\n var JSCompiler_inline_result$jscomp$0 = nextHydratableInstance;\n for (\n var inRootOrSingleton = rootOrSingletonContext;\n 8 !== JSCompiler_inline_result$jscomp$0.nodeType;\n\n ) {\n if (!inRootOrSingleton) {\n JSCompiler_inline_result$jscomp$0 = null;\n break b;\n }\n JSCompiler_inline_result$jscomp$0 = getNextHydratable(\n JSCompiler_inline_result$jscomp$0.nextSibling\n );\n if (null === JSCompiler_inline_result$jscomp$0) {\n JSCompiler_inline_result$jscomp$0 = null;\n break b;\n }\n }\n inRootOrSingleton = JSCompiler_inline_result$jscomp$0.data;\n JSCompiler_inline_result$jscomp$0 =\n \"F!\" === inRootOrSingleton || \"F\" === inRootOrSingleton\n ? JSCompiler_inline_result$jscomp$0\n : null;\n }\n if (JSCompiler_inline_result$jscomp$0) {\n nextHydratableInstance = getNextHydratable(\n JSCompiler_inline_result$jscomp$0.nextSibling\n );\n JSCompiler_inline_result =\n \"F!\" === JSCompiler_inline_result$jscomp$0.data;\n break a;\n }\n }\n throwOnHydrationMismatch(JSCompiler_inline_result);\n }\n JSCompiler_inline_result = !1;\n }\n JSCompiler_inline_result && (initialStateProp = ssrFormState[0]);\n }\n }\n ssrFormState = mountWorkInProgressHook();\n ssrFormState.memoizedState = ssrFormState.baseState = initialStateProp;\n JSCompiler_inline_result = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: actionStateReducer,\n lastRenderedState: initialStateProp\n };\n ssrFormState.queue = JSCompiler_inline_result;\n ssrFormState = dispatchSetState.bind(\n null,\n currentlyRenderingFiber,\n JSCompiler_inline_result\n );\n JSCompiler_inline_result.dispatch = ssrFormState;\n JSCompiler_inline_result = mountStateImpl(!1);\n inRootOrSingleton = dispatchOptimisticSetState.bind(\n null,\n currentlyRenderingFiber,\n !1,\n JSCompiler_inline_result.queue\n );\n JSCompiler_inline_result = mountWorkInProgressHook();\n JSCompiler_inline_result$jscomp$0 = {\n state: initialStateProp,\n dispatch: null,\n action: action,\n pending: null\n };\n JSCompiler_inline_result.queue = JSCompiler_inline_result$jscomp$0;\n ssrFormState = dispatchActionState.bind(\n null,\n currentlyRenderingFiber,\n JSCompiler_inline_result$jscomp$0,\n inRootOrSingleton,\n ssrFormState\n );\n JSCompiler_inline_result$jscomp$0.dispatch = ssrFormState;\n JSCompiler_inline_result.memoizedState = action;\n return [initialStateProp, ssrFormState, !1];\n}\nfunction updateActionState(action) {\n var stateHook = updateWorkInProgressHook();\n return updateActionStateImpl(stateHook, currentHook, action);\n}\nfunction updateActionStateImpl(stateHook, currentStateHook, action) {\n currentStateHook = updateReducerImpl(\n stateHook,\n currentStateHook,\n actionStateReducer\n )[0];\n stateHook = updateReducer(basicStateReducer)[0];\n if (\n \"object\" === typeof currentStateHook &&\n null !== currentStateHook &&\n \"function\" === typeof currentStateHook.then\n )\n try {\n var state = useThenable(currentStateHook);\n } catch (x) {\n if (x === SuspenseException) throw SuspenseActionException;\n throw x;\n }\n else state = currentStateHook;\n currentStateHook = updateWorkInProgressHook();\n var actionQueue = currentStateHook.queue,\n dispatch = actionQueue.dispatch;\n action !== currentStateHook.memoizedState &&\n ((currentlyRenderingFiber.flags |= 2048),\n pushSimpleEffect(\n 9,\n { destroy: void 0 },\n actionStateActionEffect.bind(null, actionQueue, action),\n null\n ));\n return [state, dispatch, stateHook];\n}\nfunction actionStateActionEffect(actionQueue, action) {\n actionQueue.action = action;\n}\nfunction rerenderActionState(action) {\n var stateHook = updateWorkInProgressHook(),\n currentStateHook = currentHook;\n if (null !== currentStateHook)\n return updateActionStateImpl(stateHook, currentStateHook, action);\n updateWorkInProgressHook();\n stateHook = stateHook.memoizedState;\n currentStateHook = updateWorkInProgressHook();\n var dispatch = currentStateHook.queue.dispatch;\n currentStateHook.memoizedState = action;\n return [stateHook, dispatch, !1];\n}\nfunction pushSimpleEffect(tag, inst, create, deps) {\n tag = { tag: tag, create: create, deps: deps, inst: inst, next: null };\n inst = currentlyRenderingFiber.updateQueue;\n null === inst &&\n ((inst = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = inst));\n create = inst.lastEffect;\n null === create\n ? (inst.lastEffect = tag.next = tag)\n : ((deps = create.next),\n (create.next = tag),\n (tag.next = deps),\n (inst.lastEffect = tag));\n return tag;\n}\nfunction updateRef() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction mountEffectImpl(fiberFlags, hookFlags, create, deps) {\n var hook = mountWorkInProgressHook();\n currentlyRenderingFiber.flags |= fiberFlags;\n hook.memoizedState = pushSimpleEffect(\n 1 | hookFlags,\n { destroy: void 0 },\n create,\n void 0 === deps ? null : deps\n );\n}\nfunction updateEffectImpl(fiberFlags, hookFlags, create, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var inst = hook.memoizedState.inst;\n null !== currentHook &&\n null !== deps &&\n areHookInputsEqual(deps, currentHook.memoizedState.deps)\n ? (hook.memoizedState = pushSimpleEffect(hookFlags, inst, create, deps))\n : ((currentlyRenderingFiber.flags |= fiberFlags),\n (hook.memoizedState = pushSimpleEffect(\n 1 | hookFlags,\n inst,\n create,\n deps\n )));\n}\nfunction mountEffect(create, deps) {\n mountEffectImpl(8390656, 8, create, deps);\n}\nfunction updateEffect(create, deps) {\n updateEffectImpl(2048, 8, create, deps);\n}\nfunction useEffectEventImpl(payload) {\n currentlyRenderingFiber.flags |= 4;\n var componentUpdateQueue = currentlyRenderingFiber.updateQueue;\n if (null === componentUpdateQueue)\n (componentUpdateQueue = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = componentUpdateQueue),\n (componentUpdateQueue.events = [payload]);\n else {\n var events = componentUpdateQueue.events;\n null === events\n ? (componentUpdateQueue.events = [payload])\n : events.push(payload);\n }\n}\nfunction updateEvent(callback) {\n var ref = updateWorkInProgressHook().memoizedState;\n useEffectEventImpl({ ref: ref, nextImpl: callback });\n return function () {\n if (0 !== (executionContext & 2)) throw Error(formatProdErrorMessage(440));\n return ref.impl.apply(void 0, arguments);\n };\n}\nfunction updateInsertionEffect(create, deps) {\n return updateEffectImpl(4, 2, create, deps);\n}\nfunction updateLayoutEffect(create, deps) {\n return updateEffectImpl(4, 4, create, deps);\n}\nfunction imperativeHandleEffect(create, ref) {\n if (\"function\" === typeof ref) {\n create = create();\n var refCleanup = ref(create);\n return function () {\n \"function\" === typeof refCleanup ? refCleanup() : ref(null);\n };\n }\n if (null !== ref && void 0 !== ref)\n return (\n (create = create()),\n (ref.current = create),\n function () {\n ref.current = null;\n }\n );\n}\nfunction updateImperativeHandle(ref, create, deps) {\n deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;\n updateEffectImpl(4, 4, imperativeHandleEffect.bind(null, create, ref), deps);\n}\nfunction mountDebugValue() {}\nfunction updateCallback(callback, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var prevState = hook.memoizedState;\n if (null !== deps && areHookInputsEqual(deps, prevState[1]))\n return prevState[0];\n hook.memoizedState = [callback, deps];\n return callback;\n}\nfunction updateMemo(nextCreate, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var prevState = hook.memoizedState;\n if (null !== deps && areHookInputsEqual(deps, prevState[1]))\n return prevState[0];\n prevState = nextCreate();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n nextCreate();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n hook.memoizedState = [prevState, deps];\n return prevState;\n}\nfunction mountDeferredValueImpl(hook, value, initialValue) {\n if (\n void 0 === initialValue ||\n (0 !== (renderLanes & 1073741824) &&\n 0 === (workInProgressRootRenderLanes & 261930))\n )\n return (hook.memoizedState = value);\n hook.memoizedState = initialValue;\n hook = requestDeferredLane();\n currentlyRenderingFiber.lanes |= hook;\n workInProgressRootSkippedLanes |= hook;\n return initialValue;\n}\nfunction updateDeferredValueImpl(hook, prevValue, value, initialValue) {\n if (objectIs(value, prevValue)) return value;\n if (null !== currentTreeHiddenStackCursor.current)\n return (\n (hook = mountDeferredValueImpl(hook, value, initialValue)),\n objectIs(hook, prevValue) || (didReceiveUpdate = !0),\n hook\n );\n if (\n 0 === (renderLanes & 42) ||\n (0 !== (renderLanes & 1073741824) &&\n 0 === (workInProgressRootRenderLanes & 261930))\n )\n return (didReceiveUpdate = !0), (hook.memoizedState = value);\n hook = requestDeferredLane();\n currentlyRenderingFiber.lanes |= hook;\n workInProgressRootSkippedLanes |= hook;\n return prevValue;\n}\nfunction startTransition(fiber, queue, pendingState, finishedState, callback) {\n var previousPriority = ReactDOMSharedInternals.p;\n ReactDOMSharedInternals.p =\n 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8;\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n dispatchOptimisticSetState(fiber, !1, queue, pendingState);\n try {\n var returnValue = callback(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n if (\n null !== returnValue &&\n \"object\" === typeof returnValue &&\n \"function\" === typeof returnValue.then\n ) {\n var thenableForFinishedState = chainThenableValue(\n returnValue,\n finishedState\n );\n dispatchSetStateInternal(\n fiber,\n queue,\n thenableForFinishedState,\n requestUpdateLane(fiber)\n );\n } else\n dispatchSetStateInternal(\n fiber,\n queue,\n finishedState,\n requestUpdateLane(fiber)\n );\n } catch (error) {\n dispatchSetStateInternal(\n fiber,\n queue,\n { then: function () {}, status: \"rejected\", reason: error },\n requestUpdateLane()\n );\n } finally {\n (ReactDOMSharedInternals.p = previousPriority),\n null !== prevTransition &&\n null !== currentTransition.types &&\n (prevTransition.types = currentTransition.types),\n (ReactSharedInternals.T = prevTransition);\n }\n}\nfunction noop() {}\nfunction startHostTransition(formFiber, pendingState, action, formData) {\n if (5 !== formFiber.tag) throw Error(formatProdErrorMessage(476));\n var queue = ensureFormComponentIsStateful(formFiber).queue;\n startTransition(\n formFiber,\n queue,\n pendingState,\n sharedNotPendingObject,\n null === action\n ? noop\n : function () {\n requestFormReset$1(formFiber);\n return action(formData);\n }\n );\n}\nfunction ensureFormComponentIsStateful(formFiber) {\n var existingStateHook = formFiber.memoizedState;\n if (null !== existingStateHook) return existingStateHook;\n existingStateHook = {\n memoizedState: sharedNotPendingObject,\n baseState: sharedNotPendingObject,\n baseQueue: null,\n queue: {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: sharedNotPendingObject\n },\n next: null\n };\n var initialResetState = {};\n existingStateHook.next = {\n memoizedState: initialResetState,\n baseState: initialResetState,\n baseQueue: null,\n queue: {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: initialResetState\n },\n next: null\n };\n formFiber.memoizedState = existingStateHook;\n formFiber = formFiber.alternate;\n null !== formFiber && (formFiber.memoizedState = existingStateHook);\n return existingStateHook;\n}\nfunction requestFormReset$1(formFiber) {\n var stateHook = ensureFormComponentIsStateful(formFiber);\n null === stateHook.next && (stateHook = formFiber.alternate.memoizedState);\n dispatchSetStateInternal(\n formFiber,\n stateHook.next.queue,\n {},\n requestUpdateLane()\n );\n}\nfunction useHostTransitionStatus() {\n return readContext(HostTransitionContext);\n}\nfunction updateId() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction updateRefresh() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction refreshCache(fiber) {\n for (var provider = fiber.return; null !== provider; ) {\n switch (provider.tag) {\n case 24:\n case 3:\n var lane = requestUpdateLane();\n fiber = createUpdate(lane);\n var root$69 = enqueueUpdate(provider, fiber, lane);\n null !== root$69 &&\n (scheduleUpdateOnFiber(root$69, provider, lane),\n entangleTransitions(root$69, provider, lane));\n provider = { cache: createCache() };\n fiber.payload = provider;\n return;\n }\n provider = provider.return;\n }\n}\nfunction dispatchReducerAction(fiber, queue, action) {\n var lane = requestUpdateLane();\n action = {\n lane: lane,\n revertLane: 0,\n gesture: null,\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n isRenderPhaseUpdate(fiber)\n ? enqueueRenderPhaseUpdate(queue, action)\n : ((action = enqueueConcurrentHookUpdate(fiber, queue, action, lane)),\n null !== action &&\n (scheduleUpdateOnFiber(action, fiber, lane),\n entangleTransitionUpdate(action, queue, lane)));\n}\nfunction dispatchSetState(fiber, queue, action) {\n var lane = requestUpdateLane();\n dispatchSetStateInternal(fiber, queue, action, lane);\n}\nfunction dispatchSetStateInternal(fiber, queue, action, lane) {\n var update = {\n lane: lane,\n revertLane: 0,\n gesture: null,\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update);\n else {\n var alternate = fiber.alternate;\n if (\n 0 === fiber.lanes &&\n (null === alternate || 0 === alternate.lanes) &&\n ((alternate = queue.lastRenderedReducer), null !== alternate)\n )\n try {\n var currentState = queue.lastRenderedState,\n eagerState = alternate(currentState, action);\n update.hasEagerState = !0;\n update.eagerState = eagerState;\n if (objectIs(eagerState, currentState))\n return (\n enqueueUpdate$1(fiber, queue, update, 0),\n null === workInProgressRoot && finishQueueingConcurrentUpdates(),\n !1\n );\n } catch (error) {\n } finally {\n }\n action = enqueueConcurrentHookUpdate(fiber, queue, update, lane);\n if (null !== action)\n return (\n scheduleUpdateOnFiber(action, fiber, lane),\n entangleTransitionUpdate(action, queue, lane),\n !0\n );\n }\n return !1;\n}\nfunction dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) {\n action = {\n lane: 2,\n revertLane: requestTransitionLane(),\n gesture: null,\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n if (isRenderPhaseUpdate(fiber)) {\n if (throwIfDuringRender) throw Error(formatProdErrorMessage(479));\n } else\n (throwIfDuringRender = enqueueConcurrentHookUpdate(\n fiber,\n queue,\n action,\n 2\n )),\n null !== throwIfDuringRender &&\n scheduleUpdateOnFiber(throwIfDuringRender, fiber, 2);\n}\nfunction isRenderPhaseUpdate(fiber) {\n var alternate = fiber.alternate;\n return (\n fiber === currentlyRenderingFiber ||\n (null !== alternate && alternate === currentlyRenderingFiber)\n );\n}\nfunction enqueueRenderPhaseUpdate(queue, update) {\n didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate =\n !0;\n var pending = queue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n queue.pending = update;\n}\nfunction entangleTransitionUpdate(root, queue, lane) {\n if (0 !== (lane & 4194048)) {\n var queueLanes = queue.lanes;\n queueLanes &= root.pendingLanes;\n lane |= queueLanes;\n queue.lanes = lane;\n markRootEntangled(root, lane);\n }\n}\nvar ContextOnlyDispatcher = {\n readContext: readContext,\n use: use,\n useCallback: throwInvalidHookError,\n useContext: throwInvalidHookError,\n useEffect: throwInvalidHookError,\n useImperativeHandle: throwInvalidHookError,\n useLayoutEffect: throwInvalidHookError,\n useInsertionEffect: throwInvalidHookError,\n useMemo: throwInvalidHookError,\n useReducer: throwInvalidHookError,\n useRef: throwInvalidHookError,\n useState: throwInvalidHookError,\n useDebugValue: throwInvalidHookError,\n useDeferredValue: throwInvalidHookError,\n useTransition: throwInvalidHookError,\n useSyncExternalStore: throwInvalidHookError,\n useId: throwInvalidHookError,\n useHostTransitionStatus: throwInvalidHookError,\n useFormState: throwInvalidHookError,\n useActionState: throwInvalidHookError,\n useOptimistic: throwInvalidHookError,\n useMemoCache: throwInvalidHookError,\n useCacheRefresh: throwInvalidHookError\n};\nContextOnlyDispatcher.useEffectEvent = throwInvalidHookError;\nvar HooksDispatcherOnMount = {\n readContext: readContext,\n use: use,\n useCallback: function (callback, deps) {\n mountWorkInProgressHook().memoizedState = [\n callback,\n void 0 === deps ? null : deps\n ];\n return callback;\n },\n useContext: readContext,\n useEffect: mountEffect,\n useImperativeHandle: function (ref, create, deps) {\n deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;\n mountEffectImpl(\n 4194308,\n 4,\n imperativeHandleEffect.bind(null, create, ref),\n deps\n );\n },\n useLayoutEffect: function (create, deps) {\n return mountEffectImpl(4194308, 4, create, deps);\n },\n useInsertionEffect: function (create, deps) {\n mountEffectImpl(4, 2, create, deps);\n },\n useMemo: function (nextCreate, deps) {\n var hook = mountWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var nextValue = nextCreate();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n nextCreate();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n hook.memoizedState = [nextValue, deps];\n return nextValue;\n },\n useReducer: function (reducer, initialArg, init) {\n var hook = mountWorkInProgressHook();\n if (void 0 !== init) {\n var initialState = init(initialArg);\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n init(initialArg);\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n } else initialState = initialArg;\n hook.memoizedState = hook.baseState = initialState;\n reducer = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: reducer,\n lastRenderedState: initialState\n };\n hook.queue = reducer;\n reducer = reducer.dispatch = dispatchReducerAction.bind(\n null,\n currentlyRenderingFiber,\n reducer\n );\n return [hook.memoizedState, reducer];\n },\n useRef: function (initialValue) {\n var hook = mountWorkInProgressHook();\n initialValue = { current: initialValue };\n return (hook.memoizedState = initialValue);\n },\n useState: function (initialState) {\n initialState = mountStateImpl(initialState);\n var queue = initialState.queue,\n dispatch = dispatchSetState.bind(null, currentlyRenderingFiber, queue);\n queue.dispatch = dispatch;\n return [initialState.memoizedState, dispatch];\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = mountWorkInProgressHook();\n return mountDeferredValueImpl(hook, value, initialValue);\n },\n useTransition: function () {\n var stateHook = mountStateImpl(!1);\n stateHook = startTransition.bind(\n null,\n currentlyRenderingFiber,\n stateHook.queue,\n !0,\n !1\n );\n mountWorkInProgressHook().memoizedState = stateHook;\n return [!1, stateHook];\n },\n useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {\n var fiber = currentlyRenderingFiber,\n hook = mountWorkInProgressHook();\n if (isHydrating) {\n if (void 0 === getServerSnapshot)\n throw Error(formatProdErrorMessage(407));\n getServerSnapshot = getServerSnapshot();\n } else {\n getServerSnapshot = getSnapshot();\n if (null === workInProgressRoot)\n throw Error(formatProdErrorMessage(349));\n 0 !== (workInProgressRootRenderLanes & 127) ||\n pushStoreConsistencyCheck(fiber, getSnapshot, getServerSnapshot);\n }\n hook.memoizedState = getServerSnapshot;\n var inst = { value: getServerSnapshot, getSnapshot: getSnapshot };\n hook.queue = inst;\n mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [\n subscribe\n ]);\n fiber.flags |= 2048;\n pushSimpleEffect(\n 9,\n { destroy: void 0 },\n updateStoreInstance.bind(\n null,\n fiber,\n inst,\n getServerSnapshot,\n getSnapshot\n ),\n null\n );\n return getServerSnapshot;\n },\n useId: function () {\n var hook = mountWorkInProgressHook(),\n identifierPrefix = workInProgressRoot.identifierPrefix;\n if (isHydrating) {\n var JSCompiler_inline_result = treeContextOverflow;\n var idWithLeadingBit = treeContextId;\n JSCompiler_inline_result =\n (\n idWithLeadingBit & ~(1 << (32 - clz32(idWithLeadingBit) - 1))\n ).toString(32) + JSCompiler_inline_result;\n identifierPrefix =\n \"_\" + identifierPrefix + \"R_\" + JSCompiler_inline_result;\n JSCompiler_inline_result = localIdCounter++;\n 0 < JSCompiler_inline_result &&\n (identifierPrefix += \"H\" + JSCompiler_inline_result.toString(32));\n identifierPrefix += \"_\";\n } else\n (JSCompiler_inline_result = globalClientIdCounter++),\n (identifierPrefix =\n \"_\" +\n identifierPrefix +\n \"r_\" +\n JSCompiler_inline_result.toString(32) +\n \"_\");\n return (hook.memoizedState = identifierPrefix);\n },\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: mountActionState,\n useActionState: mountActionState,\n useOptimistic: function (passthrough) {\n var hook = mountWorkInProgressHook();\n hook.memoizedState = hook.baseState = passthrough;\n var queue = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: null,\n lastRenderedState: null\n };\n hook.queue = queue;\n hook = dispatchOptimisticSetState.bind(\n null,\n currentlyRenderingFiber,\n !0,\n queue\n );\n queue.dispatch = hook;\n return [passthrough, hook];\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: function () {\n return (mountWorkInProgressHook().memoizedState = refreshCache.bind(\n null,\n currentlyRenderingFiber\n ));\n },\n useEffectEvent: function (callback) {\n var hook = mountWorkInProgressHook(),\n ref = { impl: callback };\n hook.memoizedState = ref;\n return function () {\n if (0 !== (executionContext & 2))\n throw Error(formatProdErrorMessage(440));\n return ref.impl.apply(void 0, arguments);\n };\n }\n },\n HooksDispatcherOnUpdate = {\n readContext: readContext,\n use: use,\n useCallback: updateCallback,\n useContext: readContext,\n useEffect: updateEffect,\n useImperativeHandle: updateImperativeHandle,\n useInsertionEffect: updateInsertionEffect,\n useLayoutEffect: updateLayoutEffect,\n useMemo: updateMemo,\n useReducer: updateReducer,\n useRef: updateRef,\n useState: function () {\n return updateReducer(basicStateReducer);\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = updateWorkInProgressHook();\n return updateDeferredValueImpl(\n hook,\n currentHook.memoizedState,\n value,\n initialValue\n );\n },\n useTransition: function () {\n var booleanOrThenable = updateReducer(basicStateReducer)[0],\n start = updateWorkInProgressHook().memoizedState;\n return [\n \"boolean\" === typeof booleanOrThenable\n ? booleanOrThenable\n : useThenable(booleanOrThenable),\n start\n ];\n },\n useSyncExternalStore: updateSyncExternalStore,\n useId: updateId,\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: updateActionState,\n useActionState: updateActionState,\n useOptimistic: function (passthrough, reducer) {\n var hook = updateWorkInProgressHook();\n return updateOptimisticImpl(hook, currentHook, passthrough, reducer);\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: updateRefresh\n };\nHooksDispatcherOnUpdate.useEffectEvent = updateEvent;\nvar HooksDispatcherOnRerender = {\n readContext: readContext,\n use: use,\n useCallback: updateCallback,\n useContext: readContext,\n useEffect: updateEffect,\n useImperativeHandle: updateImperativeHandle,\n useInsertionEffect: updateInsertionEffect,\n useLayoutEffect: updateLayoutEffect,\n useMemo: updateMemo,\n useReducer: rerenderReducer,\n useRef: updateRef,\n useState: function () {\n return rerenderReducer(basicStateReducer);\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = updateWorkInProgressHook();\n return null === currentHook\n ? mountDeferredValueImpl(hook, value, initialValue)\n : updateDeferredValueImpl(\n hook,\n currentHook.memoizedState,\n value,\n initialValue\n );\n },\n useTransition: function () {\n var booleanOrThenable = rerenderReducer(basicStateReducer)[0],\n start = updateWorkInProgressHook().memoizedState;\n return [\n \"boolean\" === typeof booleanOrThenable\n ? booleanOrThenable\n : useThenable(booleanOrThenable),\n start\n ];\n },\n useSyncExternalStore: updateSyncExternalStore,\n useId: updateId,\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: rerenderActionState,\n useActionState: rerenderActionState,\n useOptimistic: function (passthrough, reducer) {\n var hook = updateWorkInProgressHook();\n if (null !== currentHook)\n return updateOptimisticImpl(hook, currentHook, passthrough, reducer);\n hook.baseState = passthrough;\n return [passthrough, hook.queue.dispatch];\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: updateRefresh\n};\nHooksDispatcherOnRerender.useEffectEvent = updateEvent;\nfunction applyDerivedStateFromProps(\n workInProgress,\n ctor,\n getDerivedStateFromProps,\n nextProps\n) {\n ctor = workInProgress.memoizedState;\n getDerivedStateFromProps = getDerivedStateFromProps(nextProps, ctor);\n getDerivedStateFromProps =\n null === getDerivedStateFromProps || void 0 === getDerivedStateFromProps\n ? ctor\n : assign({}, ctor, getDerivedStateFromProps);\n workInProgress.memoizedState = getDerivedStateFromProps;\n 0 === workInProgress.lanes &&\n (workInProgress.updateQueue.baseState = getDerivedStateFromProps);\n}\nvar classComponentUpdater = {\n enqueueSetState: function (inst, payload, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.payload = payload;\n void 0 !== callback && null !== callback && (update.callback = callback);\n payload = enqueueUpdate(inst, update, lane);\n null !== payload &&\n (scheduleUpdateOnFiber(payload, inst, lane),\n entangleTransitions(payload, inst, lane));\n },\n enqueueReplaceState: function (inst, payload, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.tag = 1;\n update.payload = payload;\n void 0 !== callback && null !== callback && (update.callback = callback);\n payload = enqueueUpdate(inst, update, lane);\n null !== payload &&\n (scheduleUpdateOnFiber(payload, inst, lane),\n entangleTransitions(payload, inst, lane));\n },\n enqueueForceUpdate: function (inst, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.tag = 2;\n void 0 !== callback && null !== callback && (update.callback = callback);\n callback = enqueueUpdate(inst, update, lane);\n null !== callback &&\n (scheduleUpdateOnFiber(callback, inst, lane),\n entangleTransitions(callback, inst, lane));\n }\n};\nfunction checkShouldComponentUpdate(\n workInProgress,\n ctor,\n oldProps,\n newProps,\n oldState,\n newState,\n nextContext\n) {\n workInProgress = workInProgress.stateNode;\n return \"function\" === typeof workInProgress.shouldComponentUpdate\n ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext)\n : ctor.prototype && ctor.prototype.isPureReactComponent\n ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)\n : !0;\n}\nfunction callComponentWillReceiveProps(\n workInProgress,\n instance,\n newProps,\n nextContext\n) {\n workInProgress = instance.state;\n \"function\" === typeof instance.componentWillReceiveProps &&\n instance.componentWillReceiveProps(newProps, nextContext);\n \"function\" === typeof instance.UNSAFE_componentWillReceiveProps &&\n instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);\n instance.state !== workInProgress &&\n classComponentUpdater.enqueueReplaceState(instance, instance.state, null);\n}\nfunction resolveClassComponentProps(Component, baseProps) {\n var newProps = baseProps;\n if (\"ref\" in baseProps) {\n newProps = {};\n for (var propName in baseProps)\n \"ref\" !== propName && (newProps[propName] = baseProps[propName]);\n }\n if ((Component = Component.defaultProps)) {\n newProps === baseProps && (newProps = assign({}, newProps));\n for (var propName$73 in Component)\n void 0 === newProps[propName$73] &&\n (newProps[propName$73] = Component[propName$73]);\n }\n return newProps;\n}\nfunction defaultOnUncaughtError(error) {\n reportGlobalError(error);\n}\nfunction defaultOnCaughtError(error) {\n console.error(error);\n}\nfunction defaultOnRecoverableError(error) {\n reportGlobalError(error);\n}\nfunction logUncaughtError(root, errorInfo) {\n try {\n var onUncaughtError = root.onUncaughtError;\n onUncaughtError(errorInfo.value, { componentStack: errorInfo.stack });\n } catch (e$74) {\n setTimeout(function () {\n throw e$74;\n });\n }\n}\nfunction logCaughtError(root, boundary, errorInfo) {\n try {\n var onCaughtError = root.onCaughtError;\n onCaughtError(errorInfo.value, {\n componentStack: errorInfo.stack,\n errorBoundary: 1 === boundary.tag ? boundary.stateNode : null\n });\n } catch (e$75) {\n setTimeout(function () {\n throw e$75;\n });\n }\n}\nfunction createRootErrorUpdate(root, errorInfo, lane) {\n lane = createUpdate(lane);\n lane.tag = 3;\n lane.payload = { element: null };\n lane.callback = function () {\n logUncaughtError(root, errorInfo);\n };\n return lane;\n}\nfunction createClassErrorUpdate(lane) {\n lane = createUpdate(lane);\n lane.tag = 3;\n return lane;\n}\nfunction initializeClassErrorUpdate(update, root, fiber, errorInfo) {\n var getDerivedStateFromError = fiber.type.getDerivedStateFromError;\n if (\"function\" === typeof getDerivedStateFromError) {\n var error = errorInfo.value;\n update.payload = function () {\n return getDerivedStateFromError(error);\n };\n update.callback = function () {\n logCaughtError(root, fiber, errorInfo);\n };\n }\n var inst = fiber.stateNode;\n null !== inst &&\n \"function\" === typeof inst.componentDidCatch &&\n (update.callback = function () {\n logCaughtError(root, fiber, errorInfo);\n \"function\" !== typeof getDerivedStateFromError &&\n (null === legacyErrorBoundariesThatAlreadyFailed\n ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this]))\n : legacyErrorBoundariesThatAlreadyFailed.add(this));\n var stack = errorInfo.stack;\n this.componentDidCatch(errorInfo.value, {\n componentStack: null !== stack ? stack : \"\"\n });\n });\n}\nfunction throwException(\n root,\n returnFiber,\n sourceFiber,\n value,\n rootRenderLanes\n) {\n sourceFiber.flags |= 32768;\n if (\n null !== value &&\n \"object\" === typeof value &&\n \"function\" === typeof value.then\n ) {\n returnFiber = sourceFiber.alternate;\n null !== returnFiber &&\n propagateParentContextChanges(\n returnFiber,\n sourceFiber,\n rootRenderLanes,\n !0\n );\n sourceFiber = suspenseHandlerStackCursor.current;\n if (null !== sourceFiber) {\n switch (sourceFiber.tag) {\n case 31:\n case 13:\n return (\n null === shellBoundary\n ? renderDidSuspendDelayIfPossible()\n : null === sourceFiber.alternate &&\n 0 === workInProgressRootExitStatus &&\n (workInProgressRootExitStatus = 3),\n (sourceFiber.flags &= -257),\n (sourceFiber.flags |= 65536),\n (sourceFiber.lanes = rootRenderLanes),\n value === noopSuspenseyCommitThenable\n ? (sourceFiber.flags |= 16384)\n : ((returnFiber = sourceFiber.updateQueue),\n null === returnFiber\n ? (sourceFiber.updateQueue = new Set([value]))\n : returnFiber.add(value),\n attachPingListener(root, value, rootRenderLanes)),\n !1\n );\n case 22:\n return (\n (sourceFiber.flags |= 65536),\n value === noopSuspenseyCommitThenable\n ? (sourceFiber.flags |= 16384)\n : ((returnFiber = sourceFiber.updateQueue),\n null === returnFiber\n ? ((returnFiber = {\n transitions: null,\n markerInstances: null,\n retryQueue: new Set([value])\n }),\n (sourceFiber.updateQueue = returnFiber))\n : ((sourceFiber = returnFiber.retryQueue),\n null === sourceFiber\n ? (returnFiber.retryQueue = new Set([value]))\n : sourceFiber.add(value)),\n attachPingListener(root, value, rootRenderLanes)),\n !1\n );\n }\n throw Error(formatProdErrorMessage(435, sourceFiber.tag));\n }\n attachPingListener(root, value, rootRenderLanes);\n renderDidSuspendDelayIfPossible();\n return !1;\n }\n if (isHydrating)\n return (\n (returnFiber = suspenseHandlerStackCursor.current),\n null !== returnFiber\n ? (0 === (returnFiber.flags & 65536) && (returnFiber.flags |= 256),\n (returnFiber.flags |= 65536),\n (returnFiber.lanes = rootRenderLanes),\n value !== HydrationMismatchException &&\n ((root = Error(formatProdErrorMessage(422), { cause: value })),\n queueHydrationError(createCapturedValueAtFiber(root, sourceFiber))))\n : (value !== HydrationMismatchException &&\n ((returnFiber = Error(formatProdErrorMessage(423), {\n cause: value\n })),\n queueHydrationError(\n createCapturedValueAtFiber(returnFiber, sourceFiber)\n )),\n (root = root.current.alternate),\n (root.flags |= 65536),\n (rootRenderLanes &= -rootRenderLanes),\n (root.lanes |= rootRenderLanes),\n (value = createCapturedValueAtFiber(value, sourceFiber)),\n (rootRenderLanes = createRootErrorUpdate(\n root.stateNode,\n value,\n rootRenderLanes\n )),\n enqueueCapturedUpdate(root, rootRenderLanes),\n 4 !== workInProgressRootExitStatus &&\n (workInProgressRootExitStatus = 2)),\n !1\n );\n var wrapperError = Error(formatProdErrorMessage(520), { cause: value });\n wrapperError = createCapturedValueAtFiber(wrapperError, sourceFiber);\n null === workInProgressRootConcurrentErrors\n ? (workInProgressRootConcurrentErrors = [wrapperError])\n : workInProgressRootConcurrentErrors.push(wrapperError);\n 4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2);\n if (null === returnFiber) return !0;\n value = createCapturedValueAtFiber(value, sourceFiber);\n sourceFiber = returnFiber;\n do {\n switch (sourceFiber.tag) {\n case 3:\n return (\n (sourceFiber.flags |= 65536),\n (root = rootRenderLanes & -rootRenderLanes),\n (sourceFiber.lanes |= root),\n (root = createRootErrorUpdate(sourceFiber.stateNode, value, root)),\n enqueueCapturedUpdate(sourceFiber, root),\n !1\n );\n case 1:\n if (\n ((returnFiber = sourceFiber.type),\n (wrapperError = sourceFiber.stateNode),\n 0 === (sourceFiber.flags & 128) &&\n (\"function\" === typeof returnFiber.getDerivedStateFromError ||\n (null !== wrapperError &&\n \"function\" === typeof wrapperError.componentDidCatch &&\n (null === legacyErrorBoundariesThatAlreadyFailed ||\n !legacyErrorBoundariesThatAlreadyFailed.has(wrapperError)))))\n )\n return (\n (sourceFiber.flags |= 65536),\n (rootRenderLanes &= -rootRenderLanes),\n (sourceFiber.lanes |= rootRenderLanes),\n (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)),\n initializeClassErrorUpdate(\n rootRenderLanes,\n root,\n sourceFiber,\n value\n ),\n enqueueCapturedUpdate(sourceFiber, rootRenderLanes),\n !1\n );\n }\n sourceFiber = sourceFiber.return;\n } while (null !== sourceFiber);\n return !1;\n}\nvar SelectiveHydrationException = Error(formatProdErrorMessage(461)),\n didReceiveUpdate = !1;\nfunction reconcileChildren(current, workInProgress, nextChildren, renderLanes) {\n workInProgress.child =\n null === current\n ? mountChildFibers(workInProgress, null, nextChildren, renderLanes)\n : reconcileChildFibers(\n workInProgress,\n current.child,\n nextChildren,\n renderLanes\n );\n}\nfunction updateForwardRef(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n Component = Component.render;\n var ref = workInProgress.ref;\n if (\"ref\" in nextProps) {\n var propsWithoutRef = {};\n for (var key in nextProps)\n \"ref\" !== key && (propsWithoutRef[key] = nextProps[key]);\n } else propsWithoutRef = nextProps;\n prepareToReadContext(workInProgress);\n nextProps = renderWithHooks(\n current,\n workInProgress,\n Component,\n propsWithoutRef,\n ref,\n renderLanes\n );\n key = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && key && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, nextProps, renderLanes);\n return workInProgress.child;\n}\nfunction updateMemoComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n if (null === current) {\n var type = Component.type;\n if (\n \"function\" === typeof type &&\n !shouldConstruct(type) &&\n void 0 === type.defaultProps &&\n null === Component.compare\n )\n return (\n (workInProgress.tag = 15),\n (workInProgress.type = type),\n updateSimpleMemoComponent(\n current,\n workInProgress,\n type,\n nextProps,\n renderLanes\n )\n );\n current = createFiberFromTypeAndProps(\n Component.type,\n null,\n nextProps,\n workInProgress,\n workInProgress.mode,\n renderLanes\n );\n current.ref = workInProgress.ref;\n current.return = workInProgress;\n return (workInProgress.child = current);\n }\n type = current.child;\n if (!checkScheduledUpdateOrContext(current, renderLanes)) {\n var prevProps = type.memoizedProps;\n Component = Component.compare;\n Component = null !== Component ? Component : shallowEqual;\n if (Component(prevProps, nextProps) && current.ref === workInProgress.ref)\n return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);\n }\n workInProgress.flags |= 1;\n current = createWorkInProgress(type, nextProps);\n current.ref = workInProgress.ref;\n current.return = workInProgress;\n return (workInProgress.child = current);\n}\nfunction updateSimpleMemoComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n if (null !== current) {\n var prevProps = current.memoizedProps;\n if (\n shallowEqual(prevProps, nextProps) &&\n current.ref === workInProgress.ref\n )\n if (\n ((didReceiveUpdate = !1),\n (workInProgress.pendingProps = nextProps = prevProps),\n checkScheduledUpdateOrContext(current, renderLanes))\n )\n 0 !== (current.flags & 131072) && (didReceiveUpdate = !0);\n else\n return (\n (workInProgress.lanes = current.lanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n }\n return updateFunctionComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n );\n}\nfunction updateOffscreenComponent(\n current,\n workInProgress,\n renderLanes,\n nextProps\n) {\n var nextChildren = nextProps.children,\n prevState = null !== current ? current.memoizedState : null;\n null === current &&\n null === workInProgress.stateNode &&\n (workInProgress.stateNode = {\n _visibility: 1,\n _pendingMarkers: null,\n _retryCache: null,\n _transitions: null\n });\n if (\"hidden\" === nextProps.mode) {\n if (0 !== (workInProgress.flags & 128)) {\n prevState =\n null !== prevState ? prevState.baseLanes | renderLanes : renderLanes;\n if (null !== current) {\n nextProps = workInProgress.child = current.child;\n for (nextChildren = 0; null !== nextProps; )\n (nextChildren =\n nextChildren | nextProps.lanes | nextProps.childLanes),\n (nextProps = nextProps.sibling);\n nextProps = nextChildren & ~prevState;\n } else (nextProps = 0), (workInProgress.child = null);\n return deferHiddenOffscreenComponent(\n current,\n workInProgress,\n prevState,\n renderLanes,\n nextProps\n );\n }\n if (0 !== (renderLanes & 536870912))\n (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }),\n null !== current &&\n pushTransition(\n workInProgress,\n null !== prevState ? prevState.cachePool : null\n ),\n null !== prevState\n ? pushHiddenContext(workInProgress, prevState)\n : reuseHiddenContextOnStack(),\n pushOffscreenSuspenseHandler(workInProgress);\n else\n return (\n (nextProps = workInProgress.lanes = 536870912),\n deferHiddenOffscreenComponent(\n current,\n workInProgress,\n null !== prevState ? prevState.baseLanes | renderLanes : renderLanes,\n renderLanes,\n nextProps\n )\n );\n } else\n null !== prevState\n ? (pushTransition(workInProgress, prevState.cachePool),\n pushHiddenContext(workInProgress, prevState),\n reuseSuspenseHandlerOnStack(workInProgress),\n (workInProgress.memoizedState = null))\n : (null !== current && pushTransition(workInProgress, null),\n reuseHiddenContextOnStack(),\n reuseSuspenseHandlerOnStack(workInProgress));\n reconcileChildren(current, workInProgress, nextChildren, renderLanes);\n return workInProgress.child;\n}\nfunction bailoutOffscreenComponent(current, workInProgress) {\n (null !== current && 22 === current.tag) ||\n null !== workInProgress.stateNode ||\n (workInProgress.stateNode = {\n _visibility: 1,\n _pendingMarkers: null,\n _retryCache: null,\n _transitions: null\n });\n return workInProgress.sibling;\n}\nfunction deferHiddenOffscreenComponent(\n current,\n workInProgress,\n nextBaseLanes,\n renderLanes,\n remainingChildLanes\n) {\n var JSCompiler_inline_result = peekCacheFromPool();\n JSCompiler_inline_result =\n null === JSCompiler_inline_result\n ? null\n : { parent: CacheContext._currentValue, pool: JSCompiler_inline_result };\n workInProgress.memoizedState = {\n baseLanes: nextBaseLanes,\n cachePool: JSCompiler_inline_result\n };\n null !== current && pushTransition(workInProgress, null);\n reuseHiddenContextOnStack();\n pushOffscreenSuspenseHandler(workInProgress);\n null !== current &&\n propagateParentContextChanges(current, workInProgress, renderLanes, !0);\n workInProgress.childLanes = remainingChildLanes;\n return null;\n}\nfunction mountActivityChildren(workInProgress, nextProps) {\n nextProps = mountWorkInProgressOffscreenFiber(\n { mode: nextProps.mode, children: nextProps.children },\n workInProgress.mode\n );\n nextProps.ref = workInProgress.ref;\n workInProgress.child = nextProps;\n nextProps.return = workInProgress;\n return nextProps;\n}\nfunction retryActivityComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n) {\n reconcileChildFibers(workInProgress, current.child, null, renderLanes);\n current = mountActivityChildren(workInProgress, workInProgress.pendingProps);\n current.flags |= 2;\n popSuspenseHandler(workInProgress);\n workInProgress.memoizedState = null;\n return current;\n}\nfunction updateActivityComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n didSuspend = 0 !== (workInProgress.flags & 128);\n workInProgress.flags &= -129;\n if (null === current) {\n if (isHydrating) {\n if (\"hidden\" === nextProps.mode)\n return (\n (current = mountActivityChildren(workInProgress, nextProps)),\n (workInProgress.lanes = 536870912),\n bailoutOffscreenComponent(null, current)\n );\n pushDehydratedActivitySuspenseHandler(workInProgress);\n (current = nextHydratableInstance)\n ? ((current = canHydrateHydrationBoundary(\n current,\n rootOrSingletonContext\n )),\n (current = null !== current && \"&\" === current.data ? current : null),\n null !== current &&\n ((workInProgress.memoizedState = {\n dehydrated: current,\n treeContext:\n null !== treeContextProvider\n ? { id: treeContextId, overflow: treeContextOverflow }\n : null,\n retryLane: 536870912,\n hydrationErrors: null\n }),\n (renderLanes = createFiberFromDehydratedFragment(current)),\n (renderLanes.return = workInProgress),\n (workInProgress.child = renderLanes),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = null)))\n : (current = null);\n if (null === current) throw throwOnHydrationMismatch(workInProgress);\n workInProgress.lanes = 536870912;\n return null;\n }\n return mountActivityChildren(workInProgress, nextProps);\n }\n var prevState = current.memoizedState;\n if (null !== prevState) {\n var dehydrated = prevState.dehydrated;\n pushDehydratedActivitySuspenseHandler(workInProgress);\n if (didSuspend)\n if (workInProgress.flags & 256)\n (workInProgress.flags &= -257),\n (workInProgress = retryActivityComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n ));\n else if (null !== workInProgress.memoizedState)\n (workInProgress.child = current.child),\n (workInProgress.flags |= 128),\n (workInProgress = null);\n else throw Error(formatProdErrorMessage(558));\n else if (\n (didReceiveUpdate ||\n propagateParentContextChanges(current, workInProgress, renderLanes, !1),\n (didSuspend = 0 !== (renderLanes & current.childLanes)),\n didReceiveUpdate || didSuspend)\n ) {\n nextProps = workInProgressRoot;\n if (\n null !== nextProps &&\n ((dehydrated = getBumpedLaneForHydration(nextProps, renderLanes)),\n 0 !== dehydrated && dehydrated !== prevState.retryLane)\n )\n throw (\n ((prevState.retryLane = dehydrated),\n enqueueConcurrentRenderForLane(current, dehydrated),\n scheduleUpdateOnFiber(nextProps, current, dehydrated),\n SelectiveHydrationException)\n );\n renderDidSuspendDelayIfPossible();\n workInProgress = retryActivityComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n );\n } else\n (current = prevState.treeContext),\n (nextHydratableInstance = getNextHydratable(dehydrated.nextSibling)),\n (hydrationParentFiber = workInProgress),\n (isHydrating = !0),\n (hydrationErrors = null),\n (rootOrSingletonContext = !1),\n null !== current &&\n restoreSuspendedTreeContext(workInProgress, current),\n (workInProgress = mountActivityChildren(workInProgress, nextProps)),\n (workInProgress.flags |= 4096);\n return workInProgress;\n }\n current = createWorkInProgress(current.child, {\n mode: nextProps.mode,\n children: nextProps.children\n });\n current.ref = workInProgress.ref;\n workInProgress.child = current;\n current.return = workInProgress;\n return current;\n}\nfunction markRef(current, workInProgress) {\n var ref = workInProgress.ref;\n if (null === ref)\n null !== current &&\n null !== current.ref &&\n (workInProgress.flags |= 4194816);\n else {\n if (\"function\" !== typeof ref && \"object\" !== typeof ref)\n throw Error(formatProdErrorMessage(284));\n if (null === current || current.ref !== ref)\n workInProgress.flags |= 4194816;\n }\n}\nfunction updateFunctionComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n Component = renderWithHooks(\n current,\n workInProgress,\n Component,\n nextProps,\n void 0,\n renderLanes\n );\n nextProps = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && nextProps && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, Component, renderLanes);\n return workInProgress.child;\n}\nfunction replayFunctionComponent(\n current,\n workInProgress,\n nextProps,\n Component,\n secondArg,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n workInProgress.updateQueue = null;\n nextProps = renderWithHooksAgain(\n workInProgress,\n Component,\n nextProps,\n secondArg\n );\n finishRenderingHooks(current);\n Component = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && Component && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, nextProps, renderLanes);\n return workInProgress.child;\n}\nfunction updateClassComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n if (null === workInProgress.stateNode) {\n var context = emptyContextObject,\n contextType = Component.contextType;\n \"object\" === typeof contextType &&\n null !== contextType &&\n (context = readContext(contextType));\n context = new Component(nextProps, context);\n workInProgress.memoizedState =\n null !== context.state && void 0 !== context.state ? context.state : null;\n context.updater = classComponentUpdater;\n workInProgress.stateNode = context;\n context._reactInternals = workInProgress;\n context = workInProgress.stateNode;\n context.props = nextProps;\n context.state = workInProgress.memoizedState;\n context.refs = {};\n initializeUpdateQueue(workInProgress);\n contextType = Component.contextType;\n context.context =\n \"object\" === typeof contextType && null !== contextType\n ? readContext(contextType)\n : emptyContextObject;\n context.state = workInProgress.memoizedState;\n contextType = Component.getDerivedStateFromProps;\n \"function\" === typeof contextType &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n contextType,\n nextProps\n ),\n (context.state = workInProgress.memoizedState));\n \"function\" === typeof Component.getDerivedStateFromProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate ||\n (\"function\" !== typeof context.UNSAFE_componentWillMount &&\n \"function\" !== typeof context.componentWillMount) ||\n ((contextType = context.state),\n \"function\" === typeof context.componentWillMount &&\n context.componentWillMount(),\n \"function\" === typeof context.UNSAFE_componentWillMount &&\n context.UNSAFE_componentWillMount(),\n contextType !== context.state &&\n classComponentUpdater.enqueueReplaceState(context, context.state, null),\n processUpdateQueue(workInProgress, nextProps, context, renderLanes),\n suspendIfUpdateReadFromEntangledAsyncAction(),\n (context.state = workInProgress.memoizedState));\n \"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308);\n nextProps = !0;\n } else if (null === current) {\n context = workInProgress.stateNode;\n var unresolvedOldProps = workInProgress.memoizedProps,\n oldProps = resolveClassComponentProps(Component, unresolvedOldProps);\n context.props = oldProps;\n var oldContext = context.context,\n contextType$jscomp$0 = Component.contextType;\n contextType = emptyContextObject;\n \"object\" === typeof contextType$jscomp$0 &&\n null !== contextType$jscomp$0 &&\n (contextType = readContext(contextType$jscomp$0));\n var getDerivedStateFromProps = Component.getDerivedStateFromProps;\n contextType$jscomp$0 =\n \"function\" === typeof getDerivedStateFromProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate;\n unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps;\n contextType$jscomp$0 ||\n (\"function\" !== typeof context.UNSAFE_componentWillReceiveProps &&\n \"function\" !== typeof context.componentWillReceiveProps) ||\n ((unresolvedOldProps || oldContext !== contextType) &&\n callComponentWillReceiveProps(\n workInProgress,\n context,\n nextProps,\n contextType\n ));\n hasForceUpdate = !1;\n var oldState = workInProgress.memoizedState;\n context.state = oldState;\n processUpdateQueue(workInProgress, nextProps, context, renderLanes);\n suspendIfUpdateReadFromEntangledAsyncAction();\n oldContext = workInProgress.memoizedState;\n unresolvedOldProps || oldState !== oldContext || hasForceUpdate\n ? (\"function\" === typeof getDerivedStateFromProps &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n getDerivedStateFromProps,\n nextProps\n ),\n (oldContext = workInProgress.memoizedState)),\n (oldProps =\n hasForceUpdate ||\n checkShouldComponentUpdate(\n workInProgress,\n Component,\n oldProps,\n nextProps,\n oldState,\n oldContext,\n contextType\n ))\n ? (contextType$jscomp$0 ||\n (\"function\" !== typeof context.UNSAFE_componentWillMount &&\n \"function\" !== typeof context.componentWillMount) ||\n (\"function\" === typeof context.componentWillMount &&\n context.componentWillMount(),\n \"function\" === typeof context.UNSAFE_componentWillMount &&\n context.UNSAFE_componentWillMount()),\n \"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308))\n : (\"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308),\n (workInProgress.memoizedProps = nextProps),\n (workInProgress.memoizedState = oldContext)),\n (context.props = nextProps),\n (context.state = oldContext),\n (context.context = contextType),\n (nextProps = oldProps))\n : (\"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308),\n (nextProps = !1));\n } else {\n context = workInProgress.stateNode;\n cloneUpdateQueue(current, workInProgress);\n contextType = workInProgress.memoizedProps;\n contextType$jscomp$0 = resolveClassComponentProps(Component, contextType);\n context.props = contextType$jscomp$0;\n getDerivedStateFromProps = workInProgress.pendingProps;\n oldState = context.context;\n oldContext = Component.contextType;\n oldProps = emptyContextObject;\n \"object\" === typeof oldContext &&\n null !== oldContext &&\n (oldProps = readContext(oldContext));\n unresolvedOldProps = Component.getDerivedStateFromProps;\n (oldContext =\n \"function\" === typeof unresolvedOldProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate) ||\n (\"function\" !== typeof context.UNSAFE_componentWillReceiveProps &&\n \"function\" !== typeof context.componentWillReceiveProps) ||\n ((contextType !== getDerivedStateFromProps || oldState !== oldProps) &&\n callComponentWillReceiveProps(\n workInProgress,\n context,\n nextProps,\n oldProps\n ));\n hasForceUpdate = !1;\n oldState = workInProgress.memoizedState;\n context.state = oldState;\n processUpdateQueue(workInProgress, nextProps, context, renderLanes);\n suspendIfUpdateReadFromEntangledAsyncAction();\n var newState = workInProgress.memoizedState;\n contextType !== getDerivedStateFromProps ||\n oldState !== newState ||\n hasForceUpdate ||\n (null !== current &&\n null !== current.dependencies &&\n checkIfContextChanged(current.dependencies))\n ? (\"function\" === typeof unresolvedOldProps &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n unresolvedOldProps,\n nextProps\n ),\n (newState = workInProgress.memoizedState)),\n (contextType$jscomp$0 =\n hasForceUpdate ||\n checkShouldComponentUpdate(\n workInProgress,\n Component,\n contextType$jscomp$0,\n nextProps,\n oldState,\n newState,\n oldProps\n ) ||\n (null !== current &&\n null !== current.dependencies &&\n checkIfContextChanged(current.dependencies)))\n ? (oldContext ||\n (\"function\" !== typeof context.UNSAFE_componentWillUpdate &&\n \"function\" !== typeof context.componentWillUpdate) ||\n (\"function\" === typeof context.componentWillUpdate &&\n context.componentWillUpdate(nextProps, newState, oldProps),\n \"function\" === typeof context.UNSAFE_componentWillUpdate &&\n context.UNSAFE_componentWillUpdate(\n nextProps,\n newState,\n oldProps\n )),\n \"function\" === typeof context.componentDidUpdate &&\n (workInProgress.flags |= 4),\n \"function\" === typeof context.getSnapshotBeforeUpdate &&\n (workInProgress.flags |= 1024))\n : (\"function\" !== typeof context.componentDidUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 4),\n \"function\" !== typeof context.getSnapshotBeforeUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 1024),\n (workInProgress.memoizedProps = nextProps),\n (workInProgress.memoizedState = newState)),\n (context.props = nextProps),\n (context.state = newState),\n (context.context = oldProps),\n (nextProps = contextType$jscomp$0))\n : (\"function\" !== typeof context.componentDidUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 4),\n \"function\" !== typeof context.getSnapshotBeforeUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 1024),\n (nextProps = !1));\n }\n context = nextProps;\n markRef(current, workInProgress);\n nextProps = 0 !== (workInProgress.flags & 128);\n context || nextProps\n ? ((context = workInProgress.stateNode),\n (Component =\n nextProps && \"function\" !== typeof Component.getDerivedStateFromError\n ? null\n : context.render()),\n (workInProgress.flags |= 1),\n null !== current && nextProps\n ? ((workInProgress.child = reconcileChildFibers(\n workInProgress,\n current.child,\n null,\n renderLanes\n )),\n (workInProgress.child = reconcileChildFibers(\n workInProgress,\n null,\n Component,\n renderLanes\n )))\n : reconcileChildren(current, workInProgress, Component, renderLanes),\n (workInProgress.memoizedState = context.state),\n (current = workInProgress.child))\n : (current = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n ));\n return current;\n}\nfunction mountHostRootWithoutHydrating(\n current,\n workInProgress,\n nextChildren,\n renderLanes\n) {\n resetHydrationState();\n workInProgress.flags |= 256;\n reconcileChildren(current, workInProgress, nextChildren, renderLanes);\n return workInProgress.child;\n}\nvar SUSPENDED_MARKER = {\n dehydrated: null,\n treeContext: null,\n retryLane: 0,\n hydrationErrors: null\n};\nfunction mountSuspenseOffscreenState(renderLanes) {\n return { baseLanes: renderLanes, cachePool: getSuspendedCache() };\n}\nfunction getRemainingWorkInPrimaryTree(\n current,\n primaryTreeDidDefer,\n renderLanes\n) {\n current = null !== current ? current.childLanes & ~renderLanes : 0;\n primaryTreeDidDefer && (current |= workInProgressDeferredLane);\n return current;\n}\nfunction updateSuspenseComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n showFallback = !1,\n didSuspend = 0 !== (workInProgress.flags & 128),\n JSCompiler_temp;\n (JSCompiler_temp = didSuspend) ||\n (JSCompiler_temp =\n null !== current && null === current.memoizedState\n ? !1\n : 0 !== (suspenseStackCursor.current & 2));\n JSCompiler_temp && ((showFallback = !0), (workInProgress.flags &= -129));\n JSCompiler_temp = 0 !== (workInProgress.flags & 32);\n workInProgress.flags &= -33;\n if (null === current) {\n if (isHydrating) {\n showFallback\n ? pushPrimaryTreeSuspenseHandler(workInProgress)\n : reuseSuspenseHandlerOnStack(workInProgress);\n (current = nextHydratableInstance)\n ? ((current = canHydrateHydrationBoundary(\n current,\n rootOrSingletonContext\n )),\n (current = null !== current && \"&\" !== current.data ? current : null),\n null !== current &&\n ((workInProgress.memoizedState = {\n dehydrated: current,\n treeContext:\n null !== treeContextProvider\n ? { id: treeContextId, overflow: treeContextOverflow }\n : null,\n retryLane: 536870912,\n hydrationErrors: null\n }),\n (renderLanes = createFiberFromDehydratedFragment(current)),\n (renderLanes.return = workInProgress),\n (workInProgress.child = renderLanes),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = null)))\n : (current = null);\n if (null === current) throw throwOnHydrationMismatch(workInProgress);\n isSuspenseInstanceFallback(current)\n ? (workInProgress.lanes = 32)\n : (workInProgress.lanes = 536870912);\n return null;\n }\n var nextPrimaryChildren = nextProps.children;\n nextProps = nextProps.fallback;\n if (showFallback)\n return (\n reuseSuspenseHandlerOnStack(workInProgress),\n (showFallback = workInProgress.mode),\n (nextPrimaryChildren = mountWorkInProgressOffscreenFiber(\n { mode: \"hidden\", children: nextPrimaryChildren },\n showFallback\n )),\n (nextProps = createFiberFromFragment(\n nextProps,\n showFallback,\n renderLanes,\n null\n )),\n (nextPrimaryChildren.return = workInProgress),\n (nextProps.return = workInProgress),\n (nextPrimaryChildren.sibling = nextProps),\n (workInProgress.child = nextPrimaryChildren),\n (nextProps = workInProgress.child),\n (nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes)),\n (nextProps.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n bailoutOffscreenComponent(null, nextProps)\n );\n pushPrimaryTreeSuspenseHandler(workInProgress);\n return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);\n }\n var prevState = current.memoizedState;\n if (\n null !== prevState &&\n ((nextPrimaryChildren = prevState.dehydrated), null !== nextPrimaryChildren)\n ) {\n if (didSuspend)\n workInProgress.flags & 256\n ? (pushPrimaryTreeSuspenseHandler(workInProgress),\n (workInProgress.flags &= -257),\n (workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n )))\n : null !== workInProgress.memoizedState\n ? (reuseSuspenseHandlerOnStack(workInProgress),\n (workInProgress.child = current.child),\n (workInProgress.flags |= 128),\n (workInProgress = null))\n : (reuseSuspenseHandlerOnStack(workInProgress),\n (nextPrimaryChildren = nextProps.fallback),\n (showFallback = workInProgress.mode),\n (nextProps = mountWorkInProgressOffscreenFiber(\n { mode: \"visible\", children: nextProps.children },\n showFallback\n )),\n (nextPrimaryChildren = createFiberFromFragment(\n nextPrimaryChildren,\n showFallback,\n renderLanes,\n null\n )),\n (nextPrimaryChildren.flags |= 2),\n (nextProps.return = workInProgress),\n (nextPrimaryChildren.return = workInProgress),\n (nextProps.sibling = nextPrimaryChildren),\n (workInProgress.child = nextProps),\n reconcileChildFibers(\n workInProgress,\n current.child,\n null,\n renderLanes\n ),\n (nextProps = workInProgress.child),\n (nextProps.memoizedState =\n mountSuspenseOffscreenState(renderLanes)),\n (nextProps.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n (workInProgress = bailoutOffscreenComponent(null, nextProps)));\n else if (\n (pushPrimaryTreeSuspenseHandler(workInProgress),\n isSuspenseInstanceFallback(nextPrimaryChildren))\n ) {\n JSCompiler_temp =\n nextPrimaryChildren.nextSibling &&\n nextPrimaryChildren.nextSibling.dataset;\n if (JSCompiler_temp) var digest = JSCompiler_temp.dgst;\n JSCompiler_temp = digest;\n nextProps = Error(formatProdErrorMessage(419));\n nextProps.stack = \"\";\n nextProps.digest = JSCompiler_temp;\n queueHydrationError({ value: nextProps, source: null, stack: null });\n workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n );\n } else if (\n (didReceiveUpdate ||\n propagateParentContextChanges(current, workInProgress, renderLanes, !1),\n (JSCompiler_temp = 0 !== (renderLanes & current.childLanes)),\n didReceiveUpdate || JSCompiler_temp)\n ) {\n JSCompiler_temp = workInProgressRoot;\n if (\n null !== JSCompiler_temp &&\n ((nextProps = getBumpedLaneForHydration(JSCompiler_temp, renderLanes)),\n 0 !== nextProps && nextProps !== prevState.retryLane)\n )\n throw (\n ((prevState.retryLane = nextProps),\n enqueueConcurrentRenderForLane(current, nextProps),\n scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps),\n SelectiveHydrationException)\n );\n isSuspenseInstancePending(nextPrimaryChildren) ||\n renderDidSuspendDelayIfPossible();\n workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n );\n } else\n isSuspenseInstancePending(nextPrimaryChildren)\n ? ((workInProgress.flags |= 192),\n (workInProgress.child = current.child),\n (workInProgress = null))\n : ((current = prevState.treeContext),\n (nextHydratableInstance = getNextHydratable(\n nextPrimaryChildren.nextSibling\n )),\n (hydrationParentFiber = workInProgress),\n (isHydrating = !0),\n (hydrationErrors = null),\n (rootOrSingletonContext = !1),\n null !== current &&\n restoreSuspendedTreeContext(workInProgress, current),\n (workInProgress = mountSuspensePrimaryChildren(\n workInProgress,\n nextProps.children\n )),\n (workInProgress.flags |= 4096));\n return workInProgress;\n }\n if (showFallback)\n return (\n reuseSuspenseHandlerOnStack(workInProgress),\n (nextPrimaryChildren = nextProps.fallback),\n (showFallback = workInProgress.mode),\n (prevState = current.child),\n (digest = prevState.sibling),\n (nextProps = createWorkInProgress(prevState, {\n mode: \"hidden\",\n children: nextProps.children\n })),\n (nextProps.subtreeFlags = prevState.subtreeFlags & 65011712),\n null !== digest\n ? (nextPrimaryChildren = createWorkInProgress(\n digest,\n nextPrimaryChildren\n ))\n : ((nextPrimaryChildren = createFiberFromFragment(\n nextPrimaryChildren,\n showFallback,\n renderLanes,\n null\n )),\n (nextPrimaryChildren.flags |= 2)),\n (nextPrimaryChildren.return = workInProgress),\n (nextProps.return = workInProgress),\n (nextProps.sibling = nextPrimaryChildren),\n (workInProgress.child = nextProps),\n bailoutOffscreenComponent(null, nextProps),\n (nextProps = workInProgress.child),\n (nextPrimaryChildren = current.child.memoizedState),\n null === nextPrimaryChildren\n ? (nextPrimaryChildren = mountSuspenseOffscreenState(renderLanes))\n : ((showFallback = nextPrimaryChildren.cachePool),\n null !== showFallback\n ? ((prevState = CacheContext._currentValue),\n (showFallback =\n showFallback.parent !== prevState\n ? { parent: prevState, pool: prevState }\n : showFallback))\n : (showFallback = getSuspendedCache()),\n (nextPrimaryChildren = {\n baseLanes: nextPrimaryChildren.baseLanes | renderLanes,\n cachePool: showFallback\n })),\n (nextProps.memoizedState = nextPrimaryChildren),\n (nextProps.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n bailoutOffscreenComponent(current.child, nextProps)\n );\n pushPrimaryTreeSuspenseHandler(workInProgress);\n renderLanes = current.child;\n current = renderLanes.sibling;\n renderLanes = createWorkInProgress(renderLanes, {\n mode: \"visible\",\n children: nextProps.children\n });\n renderLanes.return = workInProgress;\n renderLanes.sibling = null;\n null !== current &&\n ((JSCompiler_temp = workInProgress.deletions),\n null === JSCompiler_temp\n ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16))\n : JSCompiler_temp.push(current));\n workInProgress.child = renderLanes;\n workInProgress.memoizedState = null;\n return renderLanes;\n}\nfunction mountSuspensePrimaryChildren(workInProgress, primaryChildren) {\n primaryChildren = mountWorkInProgressOffscreenFiber(\n { mode: \"visible\", children: primaryChildren },\n workInProgress.mode\n );\n primaryChildren.return = workInProgress;\n return (workInProgress.child = primaryChildren);\n}\nfunction mountWorkInProgressOffscreenFiber(offscreenProps, mode) {\n offscreenProps = createFiberImplClass(22, offscreenProps, null, mode);\n offscreenProps.lanes = 0;\n return offscreenProps;\n}\nfunction retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n) {\n reconcileChildFibers(workInProgress, current.child, null, renderLanes);\n current = mountSuspensePrimaryChildren(\n workInProgress,\n workInProgress.pendingProps.children\n );\n current.flags |= 2;\n workInProgress.memoizedState = null;\n return current;\n}\nfunction scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {\n fiber.lanes |= renderLanes;\n var alternate = fiber.alternate;\n null !== alternate && (alternate.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);\n}\nfunction initSuspenseListRenderState(\n workInProgress,\n isBackwards,\n tail,\n lastContentRow,\n tailMode,\n treeForkCount\n) {\n var renderState = workInProgress.memoizedState;\n null === renderState\n ? (workInProgress.memoizedState = {\n isBackwards: isBackwards,\n rendering: null,\n renderingStartTime: 0,\n last: lastContentRow,\n tail: tail,\n tailMode: tailMode,\n treeForkCount: treeForkCount\n })\n : ((renderState.isBackwards = isBackwards),\n (renderState.rendering = null),\n (renderState.renderingStartTime = 0),\n (renderState.last = lastContentRow),\n (renderState.tail = tail),\n (renderState.tailMode = tailMode),\n (renderState.treeForkCount = treeForkCount));\n}\nfunction updateSuspenseListComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n revealOrder = nextProps.revealOrder,\n tailMode = nextProps.tail;\n nextProps = nextProps.children;\n var suspenseContext = suspenseStackCursor.current,\n shouldForceFallback = 0 !== (suspenseContext & 2);\n shouldForceFallback\n ? ((suspenseContext = (suspenseContext & 1) | 2),\n (workInProgress.flags |= 128))\n : (suspenseContext &= 1);\n push(suspenseStackCursor, suspenseContext);\n reconcileChildren(current, workInProgress, nextProps, renderLanes);\n nextProps = isHydrating ? treeForkCount : 0;\n if (!shouldForceFallback && null !== current && 0 !== (current.flags & 128))\n a: for (current = workInProgress.child; null !== current; ) {\n if (13 === current.tag)\n null !== current.memoizedState &&\n scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress);\n else if (19 === current.tag)\n scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress);\n else if (null !== current.child) {\n current.child.return = current;\n current = current.child;\n continue;\n }\n if (current === workInProgress) break a;\n for (; null === current.sibling; ) {\n if (null === current.return || current.return === workInProgress)\n break a;\n current = current.return;\n }\n current.sibling.return = current.return;\n current = current.sibling;\n }\n switch (revealOrder) {\n case \"forwards\":\n renderLanes = workInProgress.child;\n for (revealOrder = null; null !== renderLanes; )\n (current = renderLanes.alternate),\n null !== current &&\n null === findFirstSuspended(current) &&\n (revealOrder = renderLanes),\n (renderLanes = renderLanes.sibling);\n renderLanes = revealOrder;\n null === renderLanes\n ? ((revealOrder = workInProgress.child), (workInProgress.child = null))\n : ((revealOrder = renderLanes.sibling), (renderLanes.sibling = null));\n initSuspenseListRenderState(\n workInProgress,\n !1,\n revealOrder,\n renderLanes,\n tailMode,\n nextProps\n );\n break;\n case \"backwards\":\n case \"unstable_legacy-backwards\":\n renderLanes = null;\n revealOrder = workInProgress.child;\n for (workInProgress.child = null; null !== revealOrder; ) {\n current = revealOrder.alternate;\n if (null !== current && null === findFirstSuspended(current)) {\n workInProgress.child = revealOrder;\n break;\n }\n current = revealOrder.sibling;\n revealOrder.sibling = renderLanes;\n renderLanes = revealOrder;\n revealOrder = current;\n }\n initSuspenseListRenderState(\n workInProgress,\n !0,\n renderLanes,\n null,\n tailMode,\n nextProps\n );\n break;\n case \"together\":\n initSuspenseListRenderState(\n workInProgress,\n !1,\n null,\n null,\n void 0,\n nextProps\n );\n break;\n default:\n workInProgress.memoizedState = null;\n }\n return workInProgress.child;\n}\nfunction bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {\n null !== current && (workInProgress.dependencies = current.dependencies);\n workInProgressRootSkippedLanes |= workInProgress.lanes;\n if (0 === (renderLanes & workInProgress.childLanes))\n if (null !== current) {\n if (\n (propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n !1\n ),\n 0 === (renderLanes & workInProgress.childLanes))\n )\n return null;\n } else return null;\n if (null !== current && workInProgress.child !== current.child)\n throw Error(formatProdErrorMessage(153));\n if (null !== workInProgress.child) {\n current = workInProgress.child;\n renderLanes = createWorkInProgress(current, current.pendingProps);\n workInProgress.child = renderLanes;\n for (renderLanes.return = workInProgress; null !== current.sibling; )\n (current = current.sibling),\n (renderLanes = renderLanes.sibling =\n createWorkInProgress(current, current.pendingProps)),\n (renderLanes.return = workInProgress);\n renderLanes.sibling = null;\n }\n return workInProgress.child;\n}\nfunction checkScheduledUpdateOrContext(current, renderLanes) {\n if (0 !== (current.lanes & renderLanes)) return !0;\n current = current.dependencies;\n return null !== current && checkIfContextChanged(current) ? !0 : !1;\n}\nfunction attemptEarlyBailoutIfNoScheduledUpdate(\n current,\n workInProgress,\n renderLanes\n) {\n switch (workInProgress.tag) {\n case 3:\n pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);\n pushProvider(workInProgress, CacheContext, current.memoizedState.cache);\n resetHydrationState();\n break;\n case 27:\n case 5:\n pushHostContext(workInProgress);\n break;\n case 4:\n pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);\n break;\n case 10:\n pushProvider(\n workInProgress,\n workInProgress.type,\n workInProgress.memoizedProps.value\n );\n break;\n case 31:\n if (null !== workInProgress.memoizedState)\n return (\n (workInProgress.flags |= 128),\n pushDehydratedActivitySuspenseHandler(workInProgress),\n null\n );\n break;\n case 13:\n var state$102 = workInProgress.memoizedState;\n if (null !== state$102) {\n if (null !== state$102.dehydrated)\n return (\n pushPrimaryTreeSuspenseHandler(workInProgress),\n (workInProgress.flags |= 128),\n null\n );\n if (0 !== (renderLanes & workInProgress.child.childLanes))\n return updateSuspenseComponent(current, workInProgress, renderLanes);\n pushPrimaryTreeSuspenseHandler(workInProgress);\n current = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n );\n return null !== current ? current.sibling : null;\n }\n pushPrimaryTreeSuspenseHandler(workInProgress);\n break;\n case 19:\n var didSuspendBefore = 0 !== (current.flags & 128);\n state$102 = 0 !== (renderLanes & workInProgress.childLanes);\n state$102 ||\n (propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n !1\n ),\n (state$102 = 0 !== (renderLanes & workInProgress.childLanes)));\n if (didSuspendBefore) {\n if (state$102)\n return updateSuspenseListComponent(\n current,\n workInProgress,\n renderLanes\n );\n workInProgress.flags |= 128;\n }\n didSuspendBefore = workInProgress.memoizedState;\n null !== didSuspendBefore &&\n ((didSuspendBefore.rendering = null),\n (didSuspendBefore.tail = null),\n (didSuspendBefore.lastEffect = null));\n push(suspenseStackCursor, suspenseStackCursor.current);\n if (state$102) break;\n else return null;\n case 22:\n return (\n (workInProgress.lanes = 0),\n updateOffscreenComponent(\n current,\n workInProgress,\n renderLanes,\n workInProgress.pendingProps\n )\n );\n case 24:\n pushProvider(workInProgress, CacheContext, current.memoizedState.cache);\n }\n return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);\n}\nfunction beginWork(current, workInProgress, renderLanes) {\n if (null !== current)\n if (current.memoizedProps !== workInProgress.pendingProps)\n didReceiveUpdate = !0;\n else {\n if (\n !checkScheduledUpdateOrContext(current, renderLanes) &&\n 0 === (workInProgress.flags & 128)\n )\n return (\n (didReceiveUpdate = !1),\n attemptEarlyBailoutIfNoScheduledUpdate(\n current,\n workInProgress,\n renderLanes\n )\n );\n didReceiveUpdate = 0 !== (current.flags & 131072) ? !0 : !1;\n }\n else\n (didReceiveUpdate = !1),\n isHydrating &&\n 0 !== (workInProgress.flags & 1048576) &&\n pushTreeId(workInProgress, treeForkCount, workInProgress.index);\n workInProgress.lanes = 0;\n switch (workInProgress.tag) {\n case 16:\n a: {\n var props = workInProgress.pendingProps;\n current = resolveLazy(workInProgress.elementType);\n workInProgress.type = current;\n if (\"function\" === typeof current)\n shouldConstruct(current)\n ? ((props = resolveClassComponentProps(current, props)),\n (workInProgress.tag = 1),\n (workInProgress = updateClassComponent(\n null,\n workInProgress,\n current,\n props,\n renderLanes\n )))\n : ((workInProgress.tag = 0),\n (workInProgress = updateFunctionComponent(\n null,\n workInProgress,\n current,\n props,\n renderLanes\n )));\n else {\n if (void 0 !== current && null !== current) {\n var $$typeof = current.$$typeof;\n if ($$typeof === REACT_FORWARD_REF_TYPE) {\n workInProgress.tag = 11;\n workInProgress = updateForwardRef(\n null,\n workInProgress,\n current,\n props,\n renderLanes\n );\n break a;\n } else if ($$typeof === REACT_MEMO_TYPE) {\n workInProgress.tag = 14;\n workInProgress = updateMemoComponent(\n null,\n workInProgress,\n current,\n props,\n renderLanes\n );\n break a;\n }\n }\n workInProgress = getComponentNameFromType(current) || current;\n throw Error(formatProdErrorMessage(306, workInProgress, \"\"));\n }\n }\n return workInProgress;\n case 0:\n return updateFunctionComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 1:\n return (\n (props = workInProgress.type),\n ($$typeof = resolveClassComponentProps(\n props,\n workInProgress.pendingProps\n )),\n updateClassComponent(\n current,\n workInProgress,\n props,\n $$typeof,\n renderLanes\n )\n );\n case 3:\n a: {\n pushHostContainer(\n workInProgress,\n workInProgress.stateNode.containerInfo\n );\n if (null === current) throw Error(formatProdErrorMessage(387));\n props = workInProgress.pendingProps;\n var prevState = workInProgress.memoizedState;\n $$typeof = prevState.element;\n cloneUpdateQueue(current, workInProgress);\n processUpdateQueue(workInProgress, props, null, renderLanes);\n var nextState = workInProgress.memoizedState;\n props = nextState.cache;\n pushProvider(workInProgress, CacheContext, props);\n props !== prevState.cache &&\n propagateContextChanges(\n workInProgress,\n [CacheContext],\n renderLanes,\n !0\n );\n suspendIfUpdateReadFromEntangledAsyncAction();\n props = nextState.element;\n if (prevState.isDehydrated)\n if (\n ((prevState = {\n element: props,\n isDehydrated: !1,\n cache: nextState.cache\n }),\n (workInProgress.updateQueue.baseState = prevState),\n (workInProgress.memoizedState = prevState),\n workInProgress.flags & 256)\n ) {\n workInProgress = mountHostRootWithoutHydrating(\n current,\n workInProgress,\n props,\n renderLanes\n );\n break a;\n } else if (props !== $$typeof) {\n $$typeof = createCapturedValueAtFiber(\n Error(formatProdErrorMessage(424)),\n workInProgress\n );\n queueHydrationError($$typeof);\n workInProgress = mountHostRootWithoutHydrating(\n current,\n workInProgress,\n props,\n renderLanes\n );\n break a;\n } else {\n current = workInProgress.stateNode.containerInfo;\n switch (current.nodeType) {\n case 9:\n current = current.body;\n break;\n default:\n current =\n \"HTML\" === current.nodeName\n ? current.ownerDocument.body\n : current;\n }\n nextHydratableInstance = getNextHydratable(current.firstChild);\n hydrationParentFiber = workInProgress;\n isHydrating = !0;\n hydrationErrors = null;\n rootOrSingletonContext = !0;\n renderLanes = mountChildFibers(\n workInProgress,\n null,\n props,\n renderLanes\n );\n for (workInProgress.child = renderLanes; renderLanes; )\n (renderLanes.flags = (renderLanes.flags & -3) | 4096),\n (renderLanes = renderLanes.sibling);\n }\n else {\n resetHydrationState();\n if (props === $$typeof) {\n workInProgress = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n );\n break a;\n }\n reconcileChildren(current, workInProgress, props, renderLanes);\n }\n workInProgress = workInProgress.child;\n }\n return workInProgress;\n case 26:\n return (\n markRef(current, workInProgress),\n null === current\n ? (renderLanes = getResource(\n workInProgress.type,\n null,\n workInProgress.pendingProps,\n null\n ))\n ? (workInProgress.memoizedState = renderLanes)\n : isHydrating ||\n ((renderLanes = workInProgress.type),\n (current = workInProgress.pendingProps),\n (props = getOwnerDocumentFromRootContainer(\n rootInstanceStackCursor.current\n ).createElement(renderLanes)),\n (props[internalInstanceKey] = workInProgress),\n (props[internalPropsKey] = current),\n setInitialProperties(props, renderLanes, current),\n markNodeAsHoistable(props),\n (workInProgress.stateNode = props))\n : (workInProgress.memoizedState = getResource(\n workInProgress.type,\n current.memoizedProps,\n workInProgress.pendingProps,\n current.memoizedState\n )),\n null\n );\n case 27:\n return (\n pushHostContext(workInProgress),\n null === current &&\n isHydrating &&\n ((props = workInProgress.stateNode =\n resolveSingletonInstance(\n workInProgress.type,\n workInProgress.pendingProps,\n rootInstanceStackCursor.current\n )),\n (hydrationParentFiber = workInProgress),\n (rootOrSingletonContext = !0),\n ($$typeof = nextHydratableInstance),\n isSingletonScope(workInProgress.type)\n ? ((previousHydratableOnEnteringScopedSingleton = $$typeof),\n (nextHydratableInstance = getNextHydratable(props.firstChild)))\n : (nextHydratableInstance = $$typeof)),\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n markRef(current, workInProgress),\n null === current && (workInProgress.flags |= 4194304),\n workInProgress.child\n );\n case 5:\n if (null === current && isHydrating) {\n if (($$typeof = props = nextHydratableInstance))\n (props = canHydrateInstance(\n props,\n workInProgress.type,\n workInProgress.pendingProps,\n rootOrSingletonContext\n )),\n null !== props\n ? ((workInProgress.stateNode = props),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = getNextHydratable(props.firstChild)),\n (rootOrSingletonContext = !1),\n ($$typeof = !0))\n : ($$typeof = !1);\n $$typeof || throwOnHydrationMismatch(workInProgress);\n }\n pushHostContext(workInProgress);\n $$typeof = workInProgress.type;\n prevState = workInProgress.pendingProps;\n nextState = null !== current ? current.memoizedProps : null;\n props = prevState.children;\n shouldSetTextContent($$typeof, prevState)\n ? (props = null)\n : null !== nextState &&\n shouldSetTextContent($$typeof, nextState) &&\n (workInProgress.flags |= 32);\n null !== workInProgress.memoizedState &&\n (($$typeof = renderWithHooks(\n current,\n workInProgress,\n TransitionAwareHostComponent,\n null,\n null,\n renderLanes\n )),\n (HostTransitionContext._currentValue = $$typeof));\n markRef(current, workInProgress);\n reconcileChildren(current, workInProgress, props, renderLanes);\n return workInProgress.child;\n case 6:\n if (null === current && isHydrating) {\n if ((current = renderLanes = nextHydratableInstance))\n (renderLanes = canHydrateTextInstance(\n renderLanes,\n workInProgress.pendingProps,\n rootOrSingletonContext\n )),\n null !== renderLanes\n ? ((workInProgress.stateNode = renderLanes),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = null),\n (current = !0))\n : (current = !1);\n current || throwOnHydrationMismatch(workInProgress);\n }\n return null;\n case 13:\n return updateSuspenseComponent(current, workInProgress, renderLanes);\n case 4:\n return (\n pushHostContainer(\n workInProgress,\n workInProgress.stateNode.containerInfo\n ),\n (props = workInProgress.pendingProps),\n null === current\n ? (workInProgress.child = reconcileChildFibers(\n workInProgress,\n null,\n props,\n renderLanes\n ))\n : reconcileChildren(current, workInProgress, props, renderLanes),\n workInProgress.child\n );\n case 11:\n return updateForwardRef(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 7:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps,\n renderLanes\n ),\n workInProgress.child\n );\n case 8:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 12:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 10:\n return (\n (props = workInProgress.pendingProps),\n pushProvider(workInProgress, workInProgress.type, props.value),\n reconcileChildren(current, workInProgress, props.children, renderLanes),\n workInProgress.child\n );\n case 9:\n return (\n ($$typeof = workInProgress.type._context),\n (props = workInProgress.pendingProps.children),\n prepareToReadContext(workInProgress),\n ($$typeof = readContext($$typeof)),\n (props = props($$typeof)),\n (workInProgress.flags |= 1),\n reconcileChildren(current, workInProgress, props, renderLanes),\n workInProgress.child\n );\n case 14:\n return updateMemoComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 15:\n return updateSimpleMemoComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 19:\n return updateSuspenseListComponent(current, workInProgress, renderLanes);\n case 31:\n return updateActivityComponent(current, workInProgress, renderLanes);\n case 22:\n return updateOffscreenComponent(\n current,\n workInProgress,\n renderLanes,\n workInProgress.pendingProps\n );\n case 24:\n return (\n prepareToReadContext(workInProgress),\n (props = readContext(CacheContext)),\n null === current\n ? (($$typeof = peekCacheFromPool()),\n null === $$typeof &&\n (($$typeof = workInProgressRoot),\n (prevState = createCache()),\n ($$typeof.pooledCache = prevState),\n prevState.refCount++,\n null !== prevState && ($$typeof.pooledCacheLanes |= renderLanes),\n ($$typeof = prevState)),\n (workInProgress.memoizedState = { parent: props, cache: $$typeof }),\n initializeUpdateQueue(workInProgress),\n pushProvider(workInProgress, CacheContext, $$typeof))\n : (0 !== (current.lanes & renderLanes) &&\n (cloneUpdateQueue(current, workInProgress),\n processUpdateQueue(workInProgress, null, null, renderLanes),\n suspendIfUpdateReadFromEntangledAsyncAction()),\n ($$typeof = current.memoizedState),\n (prevState = workInProgress.memoizedState),\n $$typeof.parent !== props\n ? (($$typeof = { parent: props, cache: props }),\n (workInProgress.memoizedState = $$typeof),\n 0 === workInProgress.lanes &&\n (workInProgress.memoizedState =\n workInProgress.updateQueue.baseState =\n $$typeof),\n pushProvider(workInProgress, CacheContext, props))\n : ((props = prevState.cache),\n pushProvider(workInProgress, CacheContext, props),\n props !== $$typeof.cache &&\n propagateContextChanges(\n workInProgress,\n [CacheContext],\n renderLanes,\n !0\n ))),\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 29:\n throw workInProgress.pendingProps;\n }\n throw Error(formatProdErrorMessage(156, workInProgress.tag));\n}\nfunction markUpdate(workInProgress) {\n workInProgress.flags |= 4;\n}\nfunction preloadInstanceAndSuspendIfNeeded(\n workInProgress,\n type,\n oldProps,\n newProps,\n renderLanes\n) {\n if ((type = 0 !== (workInProgress.mode & 32))) type = !1;\n if (type) {\n if (\n ((workInProgress.flags |= 16777216),\n (renderLanes & 335544128) === renderLanes)\n )\n if (workInProgress.stateNode.complete) workInProgress.flags |= 8192;\n else if (shouldRemainOnPreviousScreen()) workInProgress.flags |= 8192;\n else\n throw (\n ((suspendedThenable = noopSuspenseyCommitThenable),\n SuspenseyCommitException)\n );\n } else workInProgress.flags &= -16777217;\n}\nfunction preloadResourceAndSuspendIfNeeded(workInProgress, resource) {\n if (\"stylesheet\" !== resource.type || 0 !== (resource.state.loading & 4))\n workInProgress.flags &= -16777217;\n else if (((workInProgress.flags |= 16777216), !preloadResource(resource)))\n if (shouldRemainOnPreviousScreen()) workInProgress.flags |= 8192;\n else\n throw (\n ((suspendedThenable = noopSuspenseyCommitThenable),\n SuspenseyCommitException)\n );\n}\nfunction scheduleRetryEffect(workInProgress, retryQueue) {\n null !== retryQueue && (workInProgress.flags |= 4);\n workInProgress.flags & 16384 &&\n ((retryQueue =\n 22 !== workInProgress.tag ? claimNextRetryLane() : 536870912),\n (workInProgress.lanes |= retryQueue),\n (workInProgressSuspendedRetryLanes |= retryQueue));\n}\nfunction cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {\n if (!isHydrating)\n switch (renderState.tailMode) {\n case \"hidden\":\n hasRenderedATailFallback = renderState.tail;\n for (var lastTailNode = null; null !== hasRenderedATailFallback; )\n null !== hasRenderedATailFallback.alternate &&\n (lastTailNode = hasRenderedATailFallback),\n (hasRenderedATailFallback = hasRenderedATailFallback.sibling);\n null === lastTailNode\n ? (renderState.tail = null)\n : (lastTailNode.sibling = null);\n break;\n case \"collapsed\":\n lastTailNode = renderState.tail;\n for (var lastTailNode$106 = null; null !== lastTailNode; )\n null !== lastTailNode.alternate && (lastTailNode$106 = lastTailNode),\n (lastTailNode = lastTailNode.sibling);\n null === lastTailNode$106\n ? hasRenderedATailFallback || null === renderState.tail\n ? (renderState.tail = null)\n : (renderState.tail.sibling = null)\n : (lastTailNode$106.sibling = null);\n }\n}\nfunction bubbleProperties(completedWork) {\n var didBailout =\n null !== completedWork.alternate &&\n completedWork.alternate.child === completedWork.child,\n newChildLanes = 0,\n subtreeFlags = 0;\n if (didBailout)\n for (var child$107 = completedWork.child; null !== child$107; )\n (newChildLanes |= child$107.lanes | child$107.childLanes),\n (subtreeFlags |= child$107.subtreeFlags & 65011712),\n (subtreeFlags |= child$107.flags & 65011712),\n (child$107.return = completedWork),\n (child$107 = child$107.sibling);\n else\n for (child$107 = completedWork.child; null !== child$107; )\n (newChildLanes |= child$107.lanes | child$107.childLanes),\n (subtreeFlags |= child$107.subtreeFlags),\n (subtreeFlags |= child$107.flags),\n (child$107.return = completedWork),\n (child$107 = child$107.sibling);\n completedWork.subtreeFlags |= subtreeFlags;\n completedWork.childLanes = newChildLanes;\n return didBailout;\n}\nfunction completeWork(current, workInProgress, renderLanes) {\n var newProps = workInProgress.pendingProps;\n popTreeContext(workInProgress);\n switch (workInProgress.tag) {\n case 16:\n case 15:\n case 0:\n case 11:\n case 7:\n case 8:\n case 12:\n case 9:\n case 14:\n return bubbleProperties(workInProgress), null;\n case 1:\n return bubbleProperties(workInProgress), null;\n case 3:\n renderLanes = workInProgress.stateNode;\n newProps = null;\n null !== current && (newProps = current.memoizedState.cache);\n workInProgress.memoizedState.cache !== newProps &&\n (workInProgress.flags |= 2048);\n popProvider(CacheContext);\n popHostContainer();\n renderLanes.pendingContext &&\n ((renderLanes.context = renderLanes.pendingContext),\n (renderLanes.pendingContext = null));\n if (null === current || null === current.child)\n popHydrationState(workInProgress)\n ? markUpdate(workInProgress)\n : null === current ||\n (current.memoizedState.isDehydrated &&\n 0 === (workInProgress.flags & 256)) ||\n ((workInProgress.flags |= 1024),\n upgradeHydrationErrorsToRecoverable());\n bubbleProperties(workInProgress);\n return null;\n case 26:\n var type = workInProgress.type,\n nextResource = workInProgress.memoizedState;\n null === current\n ? (markUpdate(workInProgress),\n null !== nextResource\n ? (bubbleProperties(workInProgress),\n preloadResourceAndSuspendIfNeeded(workInProgress, nextResource))\n : (bubbleProperties(workInProgress),\n preloadInstanceAndSuspendIfNeeded(\n workInProgress,\n type,\n null,\n newProps,\n renderLanes\n )))\n : nextResource\n ? nextResource !== current.memoizedState\n ? (markUpdate(workInProgress),\n bubbleProperties(workInProgress),\n preloadResourceAndSuspendIfNeeded(workInProgress, nextResource))\n : (bubbleProperties(workInProgress),\n (workInProgress.flags &= -16777217))\n : ((current = current.memoizedProps),\n current !== newProps && markUpdate(workInProgress),\n bubbleProperties(workInProgress),\n preloadInstanceAndSuspendIfNeeded(\n workInProgress,\n type,\n current,\n newProps,\n renderLanes\n ));\n return null;\n case 27:\n popHostContext(workInProgress);\n renderLanes = rootInstanceStackCursor.current;\n type = workInProgress.type;\n if (null !== current && null != workInProgress.stateNode)\n current.memoizedProps !== newProps && markUpdate(workInProgress);\n else {\n if (!newProps) {\n if (null === workInProgress.stateNode)\n throw Error(formatProdErrorMessage(166));\n bubbleProperties(workInProgress);\n return null;\n }\n current = contextStackCursor.current;\n popHydrationState(workInProgress)\n ? prepareToHydrateHostInstance(workInProgress, current)\n : ((current = resolveSingletonInstance(type, newProps, renderLanes)),\n (workInProgress.stateNode = current),\n markUpdate(workInProgress));\n }\n bubbleProperties(workInProgress);\n return null;\n case 5:\n popHostContext(workInProgress);\n type = workInProgress.type;\n if (null !== current && null != workInProgress.stateNode)\n current.memoizedProps !== newProps && markUpdate(workInProgress);\n else {\n if (!newProps) {\n if (null === workInProgress.stateNode)\n throw Error(formatProdErrorMessage(166));\n bubbleProperties(workInProgress);\n return null;\n }\n nextResource = contextStackCursor.current;\n if (popHydrationState(workInProgress))\n prepareToHydrateHostInstance(workInProgress, nextResource);\n else {\n var ownerDocument = getOwnerDocumentFromRootContainer(\n rootInstanceStackCursor.current\n );\n switch (nextResource) {\n case 1:\n nextResource = ownerDocument.createElementNS(\n \"http://www.w3.org/2000/svg\",\n type\n );\n break;\n case 2:\n nextResource = ownerDocument.createElementNS(\n \"http://www.w3.org/1998/Math/MathML\",\n type\n );\n break;\n default:\n switch (type) {\n case \"svg\":\n nextResource = ownerDocument.createElementNS(\n \"http://www.w3.org/2000/svg\",\n type\n );\n break;\n case \"math\":\n nextResource = ownerDocument.createElementNS(\n \"http://www.w3.org/1998/Math/MathML\",\n type\n );\n break;\n case \"script\":\n nextResource = ownerDocument.createElement(\"div\");\n nextResource.innerHTML = \" + + + + +
+ + diff --git a/internal/web/dist/index.html.br b/internal/web/dist/index.html.br new file mode 100644 index 0000000..8e39d56 Binary files /dev/null and b/internal/web/dist/index.html.br differ diff --git a/internal/web/dist/index.html.gz b/internal/web/dist/index.html.gz new file mode 100644 index 0000000..d9c494d Binary files /dev/null and b/internal/web/dist/index.html.gz differ diff --git a/internal/web/dist/vite.svg b/internal/web/dist/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/internal/web/dist/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/internal/web/static.go b/internal/web/static.go new file mode 100644 index 0000000..1f7067f --- /dev/null +++ b/internal/web/static.go @@ -0,0 +1,239 @@ +package web + +import ( + "embed" + "io" + "io/fs" + "net/http" + "path" + "path/filepath" + "strings" + "time" +) + +// NOTE: Vite outputs to web/dist with assets in dist/assets. +// If you add more nested folders in the future, include them here too. + +//go:embed dist +var distFS embed.FS + +// spaFileSystem serves embedded dist/ files with SPA fallback to index.html +type spaFileSystem struct { + fs fs.FS +} + +func (s spaFileSystem) Open(name string) (fs.File, error) { + // Normalize, strip leading slash + if strings.HasPrefix(name, "/") { + name = name[1:] + } + // Try exact file + f, err := s.fs.Open(name) + if err == nil { + return f, nil + } + + // If the requested file doesn't exist, fall back to index.html for SPA routes + // BUT only if it's not obviously a static asset extension + ext := strings.ToLower(filepath.Ext(name)) + switch ext { + case ".js", ".css", ".map", ".json", ".txt", ".ico", ".png", ".jpg", ".jpeg", + ".svg", ".webp", ".gif", ".woff", ".woff2", ".ttf", ".otf", ".eot", ".wasm", ".br", ".gz": + return nil, fs.ErrNotExist + } + + return s.fs.Open("index.html") +} + +func newDistFS() (fs.FS, error) { + return fs.Sub(distFS, "dist") +} + +// SPAHandler returns an http.Handler that serves the embedded UI (with caching) +func SPAHandler() (http.Handler, error) { + sub, err := newDistFS() + if err != nil { + return nil, err + } + spa := spaFileSystem{fs: sub} + + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.URL.Path, "/api/") || + r.URL.Path == "/api" || + strings.HasPrefix(r.URL.Path, "/swagger") || + strings.HasPrefix(r.URL.Path, "/debug/pprof") { + http.NotFound(w, r) + return + } + + filePath := strings.TrimPrefix(path.Clean(r.URL.Path), "/") + if filePath == "" { + filePath = "index.html" + } + + // Try compressed variants for assets and HTML + // NOTE: we only change *Content-Encoding*; Content-Type derives from original ext + // Always vary on Accept-Encoding + w.Header().Add("Vary", "Accept-Encoding") + + enc := r.Header.Get("Accept-Encoding") + if tryServeCompressed(w, r, spa, filePath, enc) { + return + } + + // Fallback: normal open (or SPA fallback) + f, err := spa.Open(filePath) + if err != nil { + http.NotFound(w, r) + return + } + defer f.Close() + + if strings.HasSuffix(filePath, ".html") { + w.Header().Set("Cache-Control", "no-cache") + } else { + w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + } + + info, _ := f.Stat() + modTime := time.Now() + if info != nil { + modTime = info.ModTime() + } + http.ServeContent(w, r, filePath, modTime, file{f}) + }), nil +} + +func tryServeCompressed(w http.ResponseWriter, r *http.Request, spa spaFileSystem, filePath, enc string) bool { + wantsBR := strings.Contains(enc, "br") + wantsGZ := strings.Contains(enc, "gzip") + + type cand struct { + logical string // MIME/type decision uses this (uncompressed name) + physical string // actual file we open (with .br/.gz) + enc string + } + + var cands []cand + + // 1) direct compressed variant of requested path (rare for SPA routes, but cheap to try) + if wantsBR { + cands = append(cands, cand{logical: filePath, physical: filePath + ".br", enc: "br"}) + } + if wantsGZ { + cands = append(cands, cand{logical: filePath, physical: filePath + ".gz", enc: "gzip"}) + } + + // 2) SPA route: fall back to compressed index.html + if filepath.Ext(filePath) == "" { + if wantsBR { + cands = append(cands, cand{logical: "index.html", physical: "index.html.br", enc: "br"}) + } + if wantsGZ { + cands = append(cands, cand{logical: "index.html", physical: "index.html.gz", enc: "gzip"}) + } + } + + for _, c := range cands { + f, err := spa.fs.Open(c.physical) // open EXACT path so we don't accidentally get SPA fallback + if err != nil { + continue + } + defer f.Close() + + // Cache headers + if strings.HasSuffix(c.logical, ".html") { + w.Header().Set("Cache-Control", "no-cache") + } else { + w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + } + + if ct := mimeByExt(path.Ext(c.logical)); ct != "" { + w.Header().Set("Content-Type", ct) + } + w.Header().Set("Content-Encoding", c.enc) + w.Header().Add("Vary", "Accept-Encoding") + + info, _ := f.Stat() + modTime := time.Now() + if info != nil { + modTime = info.ModTime() + } + + // Serve the precompressed bytes + http.ServeContent(w, r, c.physical, modTime, file{f}) + return true + } + return false +} + +func serveIfExists(w http.ResponseWriter, r *http.Request, spa spaFileSystem, filePath, ext, encoding string) bool { + cf := filePath + ext + f, err := spa.Open(cf) + if err != nil { + return false + } + defer f.Close() + + // Set caching headers + if strings.HasSuffix(filePath, ".html") { + w.Header().Set("Cache-Control", "no-cache") + } else { + w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + } + // Preserve original content type by extension of *uncompressed* file + if ct := mimeByExt(path.Ext(filePath)); ct != "" { + w.Header().Set("Content-Type", ct) + } + w.Header().Set("Content-Encoding", encoding) + + info, _ := f.Stat() + modTime := time.Now() + if info != nil { + modTime = info.ModTime() + } + + // Serve the compressed bytes as an io.ReadSeeker if possible + http.ServeContent(w, r, cf, modTime, file{f}) + return true +} + +func mimeByExt(ext string) string { + switch strings.ToLower(ext) { + case ".html": + return "text/html; charset=utf-8" + case ".js": + return "application/javascript" + case ".css": + return "text/css; charset=utf-8" + case ".json": + return "application/json" + case ".svg": + return "image/svg+xml" + case ".png": + return "image/png" + case ".jpg", ".jpeg": + return "image/jpeg" + case ".webp": + return "image/webp" + case ".ico": + return "image/x-icon" + case ".woff2": + return "font/woff2" + case ".woff": + return "font/woff" + default: + return "" // let Go sniff if empty + } +} + +// file wraps fs.File to implement io.ReadSeeker if possible (for ServeContent) +type file struct{ fs.File } + +func (f file) Seek(offset int64, whence int) (int64, error) { + if s, ok := f.File.(io.Seeker); ok { + return s.Seek(offset, whence) + } + // Fallback: not seekable + return 0, fs.ErrInvalid +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..f3f17e5 --- /dev/null +++ b/main.go @@ -0,0 +1,37 @@ +package main + +import "github.com/glueops/autoglue/cmd" + +// @title AutoGlue API +// @version 1.0 +// @description API for managing K3s clusters across cloud providers + +// @contact.name GlueOps + +// @BasePath /api/v1 +// @schemes http https +// @host localhost:8080 + +// @securityDefinitions.apikey BearerAuth +// @in header +// @name Authorization +// @description Bearer token authentication + +// @securityDefinitions.apikey ApiKeyAuth +// @in header +// @name X-API-KEY +// @description User API key + +// @securityDefinitions.apikey OrgKeyAuth +// @in header +// @name X-ORG-KEY +// @description Org-level key/secret authentication + +// @securityDefinitions.apikey OrgSecretAuth +// @in header +// @name X-ORG-SECRET +// @description Org-level secret + +func main() { + cmd.Execute() +} diff --git a/openapitools.json b/openapitools.json new file mode 100644 index 0000000..f052220 --- /dev/null +++ b/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.17.0" + } +} diff --git a/postgres/Dockerfile b/postgres/Dockerfile new file mode 100644 index 0000000..d7278d0 --- /dev/null +++ b/postgres/Dockerfile @@ -0,0 +1,10 @@ +FROM postgres:latest@sha256:feff5b24fedd610975a1f5e743c51a4b360437f4dc3a11acf740dcd708f413f6 + +RUN cd /var/lib/postgresql/ && \ + openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req -keyout privkey.pem && \ + openssl rsa -in privkey.pem -passin pass:abcd -out server.key && \ + openssl req -x509 -in server.req -text -key server.key -out server.crt && \ + chmod 600 server.key && \ + chown postgres:postgres server.key + +CMD ["postgres", "-c", "ssl=on", "-c", "ssl_cert_file=/var/lib/postgresql/server.crt", "-c", "ssl_key_file=/var/lib/postgresql/server.key" ] diff --git a/sdk/go/.gitignore b/sdk/go/.gitignore new file mode 100644 index 0000000..daf913b --- /dev/null +++ b/sdk/go/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/sdk/go/.openapi-generator-ignore b/sdk/go/.openapi-generator-ignore new file mode 100644 index 0000000..7484ee5 --- /dev/null +++ b/sdk/go/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/sdk/go/.openapi-generator/FILES b/sdk/go/.openapi-generator/FILES new file mode 100644 index 0000000..ea6b4b5 --- /dev/null +++ b/sdk/go/.openapi-generator/FILES @@ -0,0 +1,86 @@ +.gitignore +.travis.yml +README.md +api/openapi.yaml +api_auth.go +api_me.go +api_me_api_keys.go +api_orgs.go +api_servers.go +api_ssh.go +api_taints.go +client.go +configuration.go +docs/AuthAPI.md +docs/DtoAuthStartResponse.md +docs/DtoCreateSSHRequest.md +docs/DtoCreateServerRequest.md +docs/DtoCreateTaintRequest.md +docs/DtoJWK.md +docs/DtoJWKS.md +docs/DtoLogoutRequest.md +docs/DtoRefreshRequest.md +docs/DtoServerResponse.md +docs/DtoSshResponse.md +docs/DtoSshRevealResponse.md +docs/DtoTaintResponse.md +docs/DtoTokenPair.md +docs/DtoUpdateServerRequest.md +docs/DtoUpdateTaintRequest.md +docs/HandlersCreateUserKeyRequest.md +docs/HandlersMeResponse.md +docs/HandlersMemberOut.md +docs/HandlersMemberUpsertReq.md +docs/HandlersOrgCreateReq.md +docs/HandlersOrgKeyCreateReq.md +docs/HandlersOrgKeyCreateResp.md +docs/HandlersOrgUpdateReq.md +docs/HandlersUpdateMeRequest.md +docs/HandlersUserAPIKeyOut.md +docs/MeAPI.md +docs/MeAPIKeysAPI.md +docs/ModelsAPIKey.md +docs/ModelsOrganization.md +docs/ModelsUser.md +docs/ModelsUserEmail.md +docs/OrgsAPI.md +docs/ServersAPI.md +docs/SshAPI.md +docs/TaintsAPI.md +docs/UtilsErrorResponse.md +git_push.sh +go.mod +go.sum +model_dto_auth_start_response.go +model_dto_create_server_request.go +model_dto_create_ssh_request.go +model_dto_create_taint_request.go +model_dto_jwk.go +model_dto_jwks.go +model_dto_logout_request.go +model_dto_refresh_request.go +model_dto_server_response.go +model_dto_ssh_response.go +model_dto_ssh_reveal_response.go +model_dto_taint_response.go +model_dto_token_pair.go +model_dto_update_server_request.go +model_dto_update_taint_request.go +model_handlers_create_user_key_request.go +model_handlers_me_response.go +model_handlers_member_out.go +model_handlers_member_upsert_req.go +model_handlers_org_create_req.go +model_handlers_org_key_create_req.go +model_handlers_org_key_create_resp.go +model_handlers_org_update_req.go +model_handlers_update_me_request.go +model_handlers_user_api_key_out.go +model_models_api_key.go +model_models_organization.go +model_models_user.go +model_models_user_email.go +model_utils_error_response.go +response.go +test/api_taints_test.go +utils.go diff --git a/sdk/go/.openapi-generator/VERSION b/sdk/go/.openapi-generator/VERSION new file mode 100644 index 0000000..6328c54 --- /dev/null +++ b/sdk/go/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.17.0 diff --git a/sdk/go/.travis.yml b/sdk/go/.travis.yml new file mode 100644 index 0000000..f5cb2ce --- /dev/null +++ b/sdk/go/.travis.yml @@ -0,0 +1,8 @@ +language: go + +install: + - go get -d -v . + +script: + - go build -v ./ + diff --git a/sdk/go/README.md b/sdk/go/README.md new file mode 100644 index 0000000..5b00725 --- /dev/null +++ b/sdk/go/README.md @@ -0,0 +1,261 @@ +# Go API client for autoglue + +API for managing K3s clusters across cloud providers + +## Overview +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [OpenAPI-spec](https://www.openapis.org/) from a remote server, you can easily generate an API client. + +- API version: 1.0 +- Package version: 1.0.0 +- Generator version: 7.17.0 +- Build package: org.openapitools.codegen.languages.GoClientCodegen + +## Installation + +Install the following dependencies: + +```sh +go get github.com/stretchr/testify/assert +go get golang.org/x/net/context +``` + +Put the package under your project folder and add the following in import: + +```go +import autoglue "github.com/glueops/autoglue-sdk" +``` + +To use a proxy, set the environment variable `HTTP_PROXY`: + +```go +os.Setenv("HTTP_PROXY", "http://proxy_name:proxy_port") +``` + +## Configuration of Server URL + +Default configuration comes with `Servers` field that contains server objects as defined in the OpenAPI specification. + +### Select Server Configuration + +For using other server than the one defined on index 0 set context value `autoglue.ContextServerIndex` of type `int`. + +```go +ctx := context.WithValue(context.Background(), autoglue.ContextServerIndex, 1) +``` + +### Templated Server URL + +Templated server URL is formatted using default variables from configuration or from context value `autoglue.ContextServerVariables` of type `map[string]string`. + +```go +ctx := context.WithValue(context.Background(), autoglue.ContextServerVariables, map[string]string{ + "basePath": "v2", +}) +``` + +Note, enum values are always validated and all unused variables are silently ignored. + +### URLs Configuration per Operation + +Each operation can use different server URL defined using `OperationServers` map in the `Configuration`. +An operation is uniquely identified by `"{classname}Service.{nickname}"` string. +Similar rules for overriding default operation server index and variables applies by using `autoglue.ContextOperationServerIndices` and `autoglue.ContextOperationServerVariables` context maps. + +```go +ctx := context.WithValue(context.Background(), autoglue.ContextOperationServerIndices, map[string]int{ + "{classname}Service.{nickname}": 2, +}) +ctx = context.WithValue(context.Background(), autoglue.ContextOperationServerVariables, map[string]map[string]string{ + "{classname}Service.{nickname}": { + "port": "8443", + }, +}) +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost:8080/api/v1* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*AuthAPI* | [**AuthCallback**](docs/AuthAPI.md#authcallback) | **Get** /auth/{provider}/callback | Handle social login callback +*AuthAPI* | [**AuthStart**](docs/AuthAPI.md#authstart) | **Post** /auth/{provider}/start | Begin social login +*AuthAPI* | [**GetJWKS**](docs/AuthAPI.md#getjwks) | **Get** /.well-known/jwks.json | Get JWKS +*AuthAPI* | [**Logout**](docs/AuthAPI.md#logout) | **Post** /auth/logout | Revoke refresh token family (logout everywhere) +*AuthAPI* | [**Refresh**](docs/AuthAPI.md#refresh) | **Post** /auth/refresh | Rotate refresh token +*MeAPI* | [**GetMe**](docs/MeAPI.md#getme) | **Get** /me | Get current user profile +*MeAPI* | [**UpdateMe**](docs/MeAPI.md#updateme) | **Patch** /me | Update current user profile +*MeAPIKeysAPI* | [**CreateUserAPIKey**](docs/MeAPIKeysAPI.md#createuserapikey) | **Post** /me/api-keys | Create a new user API key +*MeAPIKeysAPI* | [**DeleteUserAPIKey**](docs/MeAPIKeysAPI.md#deleteuserapikey) | **Delete** /me/api-keys/{id} | Delete a user API key +*MeAPIKeysAPI* | [**ListUserAPIKeys**](docs/MeAPIKeysAPI.md#listuserapikeys) | **Get** /me/api-keys | List my API keys +*OrgsAPI* | [**AddOrUpdateMember**](docs/OrgsAPI.md#addorupdatemember) | **Post** /orgs/{id}/members | Add or update a member (owner/admin) +*OrgsAPI* | [**CreateOrg**](docs/OrgsAPI.md#createorg) | **Post** /orgs | Create organization +*OrgsAPI* | [**CreateOrgKey**](docs/OrgsAPI.md#createorgkey) | **Post** /orgs/{id}/api-keys | Create org key/secret pair (owner/admin) +*OrgsAPI* | [**DeleteOrg**](docs/OrgsAPI.md#deleteorg) | **Delete** /orgs/{id} | Delete organization (owner) +*OrgsAPI* | [**DeleteOrgKey**](docs/OrgsAPI.md#deleteorgkey) | **Delete** /orgs/{id}/api-keys/{key_id} | Delete org key (owner/admin) +*OrgsAPI* | [**GetOrg**](docs/OrgsAPI.md#getorg) | **Get** /orgs/{id} | Get organization +*OrgsAPI* | [**ListMembers**](docs/OrgsAPI.md#listmembers) | **Get** /orgs/{id}/members | List members in org +*OrgsAPI* | [**ListMyOrgs**](docs/OrgsAPI.md#listmyorgs) | **Get** /orgs | List organizations I belong to +*OrgsAPI* | [**ListOrgKeys**](docs/OrgsAPI.md#listorgkeys) | **Get** /orgs/{id}/api-keys | List org-scoped API keys (no secrets) +*OrgsAPI* | [**RemoveMember**](docs/OrgsAPI.md#removemember) | **Delete** /orgs/{id}/members/{user_id} | Remove a member (owner/admin) +*OrgsAPI* | [**UpdateOrg**](docs/OrgsAPI.md#updateorg) | **Patch** /orgs/{id} | Update organization (owner/admin) +*ServersAPI* | [**CreateServer**](docs/ServersAPI.md#createserver) | **Post** /servers | Create server (org scoped) +*ServersAPI* | [**DeleteServer**](docs/ServersAPI.md#deleteserver) | **Delete** /servers/{id} | Delete server (org scoped) +*ServersAPI* | [**GetServer**](docs/ServersAPI.md#getserver) | **Get** /servers/{id} | Get server by ID (org scoped) +*ServersAPI* | [**ListServers**](docs/ServersAPI.md#listservers) | **Get** /servers | List servers (org scoped) +*ServersAPI* | [**UpdateServer**](docs/ServersAPI.md#updateserver) | **Patch** /servers/{id} | Update server (org scoped) +*SshAPI* | [**CreateSSHKey**](docs/SshAPI.md#createsshkey) | **Post** /ssh | Create ssh keypair (org scoped) +*SshAPI* | [**DeleteSSHKey**](docs/SshAPI.md#deletesshkey) | **Delete** /ssh/{id} | Delete ssh keypair (org scoped) +*SshAPI* | [**DownloadSSHKey**](docs/SshAPI.md#downloadsshkey) | **Get** /ssh/{id}/download | Download ssh key files by ID (org scoped) +*SshAPI* | [**GetSSHKey**](docs/SshAPI.md#getsshkey) | **Get** /ssh/{id} | Get ssh key by ID (org scoped) +*SshAPI* | [**ListPublicSshKeys**](docs/SshAPI.md#listpublicsshkeys) | **Get** /ssh | List ssh keys (org scoped) +*TaintsAPI* | [**CreateTaint**](docs/TaintsAPI.md#createtaint) | **Post** /taints | Create node taint (org scoped) +*TaintsAPI* | [**DeleteTaint**](docs/TaintsAPI.md#deletetaint) | **Delete** /taints/{id} | Delete taint (org scoped) +*TaintsAPI* | [**GetTaint**](docs/TaintsAPI.md#gettaint) | **Get** /taints/{id} | Get node taint by ID (org scoped) +*TaintsAPI* | [**ListTaints**](docs/TaintsAPI.md#listtaints) | **Get** /taints | List node pool taints (org scoped) +*TaintsAPI* | [**UpdateTaint**](docs/TaintsAPI.md#updatetaint) | **Patch** /taints/{id} | Update node taint (org scoped) + + +## Documentation For Models + + - [DtoAuthStartResponse](docs/DtoAuthStartResponse.md) + - [DtoCreateSSHRequest](docs/DtoCreateSSHRequest.md) + - [DtoCreateServerRequest](docs/DtoCreateServerRequest.md) + - [DtoCreateTaintRequest](docs/DtoCreateTaintRequest.md) + - [DtoJWK](docs/DtoJWK.md) + - [DtoJWKS](docs/DtoJWKS.md) + - [DtoLogoutRequest](docs/DtoLogoutRequest.md) + - [DtoRefreshRequest](docs/DtoRefreshRequest.md) + - [DtoServerResponse](docs/DtoServerResponse.md) + - [DtoSshResponse](docs/DtoSshResponse.md) + - [DtoSshRevealResponse](docs/DtoSshRevealResponse.md) + - [DtoTaintResponse](docs/DtoTaintResponse.md) + - [DtoTokenPair](docs/DtoTokenPair.md) + - [DtoUpdateServerRequest](docs/DtoUpdateServerRequest.md) + - [DtoUpdateTaintRequest](docs/DtoUpdateTaintRequest.md) + - [HandlersCreateUserKeyRequest](docs/HandlersCreateUserKeyRequest.md) + - [HandlersMeResponse](docs/HandlersMeResponse.md) + - [HandlersMemberOut](docs/HandlersMemberOut.md) + - [HandlersMemberUpsertReq](docs/HandlersMemberUpsertReq.md) + - [HandlersOrgCreateReq](docs/HandlersOrgCreateReq.md) + - [HandlersOrgKeyCreateReq](docs/HandlersOrgKeyCreateReq.md) + - [HandlersOrgKeyCreateResp](docs/HandlersOrgKeyCreateResp.md) + - [HandlersOrgUpdateReq](docs/HandlersOrgUpdateReq.md) + - [HandlersUpdateMeRequest](docs/HandlersUpdateMeRequest.md) + - [HandlersUserAPIKeyOut](docs/HandlersUserAPIKeyOut.md) + - [ModelsAPIKey](docs/ModelsAPIKey.md) + - [ModelsOrganization](docs/ModelsOrganization.md) + - [ModelsUser](docs/ModelsUser.md) + - [ModelsUserEmail](docs/ModelsUserEmail.md) + - [UtilsErrorResponse](docs/UtilsErrorResponse.md) + + +## Documentation For Authorization + + +Authentication schemes defined for the API: +### ApiKeyAuth + +- **Type**: API key +- **API key parameter name**: X-API-KEY +- **Location**: HTTP header + +Note, each API key must be added to a map of `map[string]APIKey` where the key is: ApiKeyAuth and passed in as the auth context for each request. + +Example + +```go +auth := context.WithValue( + context.Background(), + autoglue.ContextAPIKeys, + map[string]autoglue.APIKey{ + "ApiKeyAuth": {Key: "API_KEY_STRING"}, + }, + ) +r, err := client.Service.Operation(auth, args) +``` + +### BearerAuth + +- **Type**: API key +- **API key parameter name**: Authorization +- **Location**: HTTP header + +Note, each API key must be added to a map of `map[string]APIKey` where the key is: BearerAuth and passed in as the auth context for each request. + +Example + +```go +auth := context.WithValue( + context.Background(), + autoglue.ContextAPIKeys, + map[string]autoglue.APIKey{ + "BearerAuth": {Key: "API_KEY_STRING"}, + }, + ) +r, err := client.Service.Operation(auth, args) +``` + +### OrgKeyAuth + +- **Type**: API key +- **API key parameter name**: X-ORG-KEY +- **Location**: HTTP header + +Note, each API key must be added to a map of `map[string]APIKey` where the key is: OrgKeyAuth and passed in as the auth context for each request. + +Example + +```go +auth := context.WithValue( + context.Background(), + autoglue.ContextAPIKeys, + map[string]autoglue.APIKey{ + "OrgKeyAuth": {Key: "API_KEY_STRING"}, + }, + ) +r, err := client.Service.Operation(auth, args) +``` + +### OrgSecretAuth + +- **Type**: API key +- **API key parameter name**: X-ORG-SECRET +- **Location**: HTTP header + +Note, each API key must be added to a map of `map[string]APIKey` where the key is: OrgSecretAuth and passed in as the auth context for each request. + +Example + +```go +auth := context.WithValue( + context.Background(), + autoglue.ContextAPIKeys, + map[string]autoglue.APIKey{ + "OrgSecretAuth": {Key: "API_KEY_STRING"}, + }, + ) +r, err := client.Service.Operation(auth, args) +``` + + +## Documentation for Utility Methods + +Due to the fact that model structure members are all pointers, this package contains +a number of utility functions to easily obtain pointers to values of basic types. +Each of these functions takes a value of the given basic type and returns a pointer to it: + +* `PtrBool` +* `PtrInt` +* `PtrInt32` +* `PtrInt64` +* `PtrFloat` +* `PtrFloat32` +* `PtrFloat64` +* `PtrString` +* `PtrTime` + +## Author + + + diff --git a/sdk/go/api/openapi.yaml b/sdk/go/api/openapi.yaml new file mode 100644 index 0000000..f17ac27 --- /dev/null +++ b/sdk/go/api/openapi.yaml @@ -0,0 +1,2086 @@ +openapi: 3.0.1 +info: + contact: + name: GlueOps + description: API for managing K3s clusters across cloud providers + title: AutoGlue API + version: "1.0" +servers: +- url: http://localhost:8080/api/v1 +- url: https://localhost:8080/api/v1 +paths: + /.well-known/jwks.json: + get: + description: Returns the JSON Web Key Set for token verification + operationId: getJWKS + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.JWKS" + description: OK + summary: Get JWKS + tags: + - Auth + /auth/logout: + post: + operationId: Logout + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/dto.LogoutRequest" + description: Refresh token + required: true + responses: + "204": + content: {} + description: No Content + summary: Revoke refresh token family (logout everywhere) + tags: + - Auth + x-codegen-request-body-name: body + /auth/refresh: + post: + operationId: Refresh + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/dto.RefreshRequest" + description: Refresh token + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.TokenPair" + description: OK + summary: Rotate refresh token + tags: + - Auth + x-codegen-request-body-name: body + /auth/{provider}/callback: + get: + operationId: AuthCallback + parameters: + - description: google|github + in: path + name: provider + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.TokenPair" + description: OK + summary: Handle social login callback + tags: + - Auth + /auth/{provider}/start: + post: + description: Returns provider authorization URL for the frontend to redirect + operationId: AuthStart + parameters: + - description: google|github + in: path + name: provider + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.AuthStartResponse" + description: OK + summary: Begin social login + tags: + - Auth + /me: + get: + operationId: GetMe + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.meResponse" + description: OK + security: + - BearerAuth: [] + - ApiKeyAuth: [] + summary: Get current user profile + tags: + - Me + patch: + operationId: UpdateMe + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.updateMeRequest" + description: Patch profile + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/models.User" + description: OK + security: + - BearerAuth: [] + - ApiKeyAuth: [] + summary: Update current user profile + tags: + - Me + x-codegen-request-body-name: body + /me/api-keys: + get: + operationId: ListUserAPIKeys + responses: + "200": + content: + application/json: + schema: + items: + $ref: "#/components/schemas/handlers.userAPIKeyOut" + type: array + description: OK + security: + - BearerAuth: [] + - ApiKeyAuth: [] + summary: List my API keys + tags: + - Me / API Keys + post: + description: Returns the plaintext key once. Store it securely on the client + side. + operationId: CreateUserAPIKey + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.createUserKeyRequest" + description: Key options + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.userAPIKeyOut" + description: Created + security: + - BearerAuth: [] + - ApiKeyAuth: [] + summary: Create a new user API key + tags: + - Me / API Keys + x-codegen-request-body-name: body + /me/api-keys/{id}: + delete: + operationId: DeleteUserAPIKey + parameters: + - description: Key ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "204": + content: {} + description: No Content + security: + - BearerAuth: [] + summary: Delete a user API key + tags: + - Me / API Keys + /orgs: + get: + operationId: listMyOrgs + responses: + "200": + content: + application/json: + schema: + items: + $ref: "#/components/schemas/models.Organization" + type: array + description: OK + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + security: + - BearerAuth: [] + summary: List organizations I belong to + tags: + - Orgs + post: + operationId: createOrg + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.orgCreateReq" + description: Org payload + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/models.Organization" + description: Created + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Conflict + security: + - BearerAuth: [] + summary: Create organization + tags: + - Orgs + x-codegen-request-body-name: body + /orgs/{id}: + delete: + operationId: deleteOrg + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "204": + content: {} + description: Deleted + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Not Found + security: + - BearerAuth: [] + summary: Delete organization (owner) + tags: + - Orgs + get: + operationId: getOrg + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/models.Organization" + description: OK + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Not Found + security: + - BearerAuth: [] + summary: Get organization + tags: + - Orgs + patch: + operationId: updateOrg + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.orgUpdateReq" + description: Update payload + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/models.Organization" + description: OK + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Not Found + security: + - BearerAuth: [] + summary: Update organization (owner/admin) + tags: + - Orgs + x-codegen-request-body-name: body + /orgs/{id}/api-keys: + get: + operationId: listOrgKeys + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + items: + $ref: "#/components/schemas/models.APIKey" + type: array + description: OK + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + security: + - BearerAuth: [] + summary: List org-scoped API keys (no secrets) + tags: + - Orgs + post: + operationId: createOrgKey + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.orgKeyCreateReq" + description: Key name + optional expiry + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.orgKeyCreateResp" + description: Created + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + security: + - BearerAuth: [] + summary: Create org key/secret pair (owner/admin) + tags: + - Orgs + x-codegen-request-body-name: body + /orgs/{id}/api-keys/{key_id}: + delete: + operationId: deleteOrgKey + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + - description: Key ID (UUID) + in: path + name: key_id + required: true + schema: + type: string + responses: + "204": + content: {} + description: Deleted + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + security: + - BearerAuth: [] + summary: Delete org key (owner/admin) + tags: + - Orgs + /orgs/{id}/members: + get: + operationId: listMembers + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + items: + $ref: "#/components/schemas/handlers.memberOut" + type: array + description: OK + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + security: + - BearerAuth: [] + summary: List members in org + tags: + - Orgs + post: + operationId: addOrUpdateMember + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.memberUpsertReq" + description: User & role + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/handlers.memberOut" + description: OK + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + security: + - BearerAuth: [] + summary: Add or update a member (owner/admin) + tags: + - Orgs + x-codegen-request-body-name: body + /orgs/{id}/members/{user_id}: + delete: + operationId: removeMember + parameters: + - description: Org ID (UUID) + in: path + name: id + required: true + schema: + type: string + - description: User ID (UUID) + in: path + name: user_id + required: true + schema: + type: string + responses: + "204": + content: {} + description: Removed + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/utils.ErrorResponse" + description: Unauthorized + security: + - BearerAuth: [] + summary: Remove a member (owner/admin) + tags: + - Orgs + /servers: + get: + description: "Returns servers for the organization in X-Org-ID. Optional filters:\ + \ status, role." + operationId: ListServers + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: Filter by status (pending|provisioning|ready|failed) + in: query + name: status + schema: + type: string + - description: Filter by role + in: query + name: role + schema: + type: string + responses: + "200": + content: + application/json: + schema: + items: + $ref: "#/components/schemas/dto.ServerResponse" + type: array + description: OK + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: failed to list servers + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: List servers (org scoped) + tags: + - Servers + post: + description: Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id + belongs to the org. + operationId: CreateServer + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/dto.CreateServerRequest" + description: Server payload + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.ServerResponse" + description: Created + "400": + content: + application/json: + schema: + type: string + description: invalid json / missing fields / invalid status / invalid ssh_key_id + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: create failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Create server (org scoped) + tags: + - Servers + x-codegen-request-body-name: body + /servers/{id}: + delete: + description: Permanently deletes the server. + operationId: DeleteServer + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: Server ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "204": + content: + application/json: + schema: + type: string + description: No Content + "400": + content: + application/json: + schema: + type: string + description: invalid id + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: delete failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Delete server (org scoped) + tags: + - Servers + get: + description: Returns one server in the given organization. + operationId: GetServer + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: Server ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.ServerResponse" + description: OK + "400": + content: + application/json: + schema: + type: string + description: invalid id + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "404": + content: + application/json: + schema: + type: string + description: not found + "500": + content: + application/json: + schema: + type: string + description: fetch failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Get server by ID (org scoped) + tags: + - Servers + patch: + description: Partially update fields; changing ssh_key_id validates ownership. + operationId: UpdateServer + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: Server ID (UUID) + in: path + name: id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/dto.UpdateServerRequest" + description: Fields to update + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.ServerResponse" + description: OK + "400": + content: + application/json: + schema: + type: string + description: invalid id / invalid json / invalid status / invalid ssh_key_id + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "404": + content: + application/json: + schema: + type: string + description: not found + "500": + content: + application/json: + schema: + type: string + description: update failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Update server (org scoped) + tags: + - Servers + x-codegen-request-body-name: body + /ssh: + get: + description: Returns ssh keys for the organization in X-Org-ID. + operationId: ListPublicSshKeys + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + responses: + "200": + content: + application/json: + schema: + items: + $ref: "#/components/schemas/dto.SshResponse" + type: array + description: OK + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: failed to list keys + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: List ssh keys (org scoped) + tags: + - Ssh + post: + description: "Generates an RSA or ED25519 keypair, saves it, and returns metadata.\ + \ For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores\ + \ bits." + operationId: CreateSSHKey + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/dto.CreateSSHRequest" + description: Key generation options + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.SshResponse" + description: Created + "400": + content: + application/json: + schema: + type: string + description: invalid json / invalid bits + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: generation/create failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Create ssh keypair (org scoped) + tags: + - Ssh + x-codegen-request-body-name: body + /ssh/{id}: + delete: + description: Permanently deletes a keypair. + operationId: DeleteSSHKey + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: SSH Key ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "204": + content: + application/json: + schema: + type: string + description: No Content + "400": + content: + application/json: + schema: + type: string + description: invalid id + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: delete failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Delete ssh keypair (org scoped) + tags: + - Ssh + get: + description: Returns public key fields. Append `?reveal=true` to include the + private key PEM. + operationId: GetSSHKey + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: SSH Key ID (UUID) + in: path + name: id + required: true + schema: + type: string + - description: Reveal private key PEM + in: query + name: reveal + schema: + type: boolean + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.SshRevealResponse" + description: When reveal=true + "400": + content: + application/json: + schema: + type: string + description: invalid id + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "404": + content: + application/json: + schema: + type: string + description: not found + "500": + content: + application/json: + schema: + type: string + description: fetch failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Get ssh key by ID (org scoped) + tags: + - Ssh + /ssh/{id}/download: + get: + description: Download `part=public|private|both` of the keypair. `both` returns + a zip file. + operationId: DownloadSSHKey + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + required: true + schema: + type: string + - description: SSH Key ID (UUID) + in: path + name: id + required: true + schema: + type: string + - description: Which part to download + in: query + name: part + required: true + schema: + enum: + - public + - private + - both + type: string + responses: + "200": + content: + application/json: + schema: + type: string + description: file content + "400": + content: + application/json: + schema: + type: string + description: invalid id / invalid part + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "404": + content: + application/json: + schema: + type: string + description: not found + "500": + content: + application/json: + schema: + type: string + description: download failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Download ssh key files by ID (org scoped) + tags: + - Ssh + /taints: + get: + description: "Returns node taints for the organization in X-Org-ID. Filters:\ + \ `key`, `value`, and `q` (key contains). Add `include=node_pools` to include\ + \ linked node pools." + operationId: ListTaints + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: Exact key + in: query + name: key + schema: + type: string + - description: Exact value + in: query + name: value + schema: + type: string + - description: key contains (case-insensitive) + in: query + name: q + schema: + type: string + responses: + "200": + content: + application/json: + schema: + items: + $ref: "#/components/schemas/dto.TaintResponse" + type: array + description: OK + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: failed to list node taints + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: List node pool taints (org scoped) + tags: + - Taints + post: + description: Creates a taint. + operationId: CreateTaint + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/dto.CreateTaintRequest" + description: Taint payload + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.TaintResponse" + description: Created + "400": + content: + application/json: + schema: + type: string + description: invalid json / missing fields / invalid node_pool_ids + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: create failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Create node taint (org scoped) + tags: + - Taints + x-codegen-request-body-name: body + /taints/{id}: + delete: + description: Permanently deletes the taint. + operationId: DeleteTaint + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: Node Taint ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "204": + content: + application/json: + schema: + type: string + description: No Content + "400": + content: + application/json: + schema: + type: string + description: invalid id + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "500": + content: + application/json: + schema: + type: string + description: delete failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Delete taint (org scoped) + tags: + - Taints + get: + operationId: GetTaint + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: Node Taint ID (UUID) + in: path + name: id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.TaintResponse" + description: OK + "400": + content: + application/json: + schema: + type: string + description: invalid id + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "404": + content: + application/json: + schema: + type: string + description: not found + "500": + content: + application/json: + schema: + type: string + description: fetch failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Get node taint by ID (org scoped) + tags: + - Taints + patch: + description: Partially update taint fields. + operationId: UpdateTaint + parameters: + - description: Organization UUID + in: header + name: X-Org-ID + schema: + type: string + - description: Node Taint ID (UUID) + in: path + name: id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/dto.UpdateTaintRequest" + description: Fields to update + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/dto.TaintResponse" + description: OK + "400": + content: + application/json: + schema: + type: string + description: invalid id / invalid json + "401": + content: + application/json: + schema: + type: string + description: Unauthorized + "403": + content: + application/json: + schema: + type: string + description: organization required + "404": + content: + application/json: + schema: + type: string + description: not found + "500": + content: + application/json: + schema: + type: string + description: update failed + security: + - BearerAuth: [] + - OrgKeyAuth: [] + - OrgSecretAuth: [] + summary: Update node taint (org scoped) + tags: + - Taints + x-codegen-request-body-name: body +components: + schemas: + dto.AuthStartResponse: + example: + auth_url: https://accounts.google.com/o/oauth2/v2/auth?client_id=... + properties: + auth_url: + example: https://accounts.google.com/o/oauth2/v2/auth?client_id=... + type: string + type: object + dto.CreateSSHRequest: + properties: + bits: + description: Only for RSA + type: integer + comment: + example: deploy@autoglue + type: string + name: + type: string + type: + description: '"rsa" (default) or "ed25519"' + type: string + type: object + dto.CreateServerRequest: + properties: + hostname: + type: string + private_ip_address: + type: string + public_ip_address: + type: string + role: + example: master|worker|bastion + type: string + ssh_key_id: + type: string + ssh_user: + type: string + status: + example: pending|provisioning|ready|failed + type: string + type: object + dto.CreateTaintRequest: + properties: + effect: + type: string + key: + type: string + value: + type: string + type: object + dto.JWK: + example: + kty: RSA + e: AQAB + use: sig + kid: 7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345 + x: x + alg: RS256 + "n": "n" + properties: + alg: + example: RS256 + type: string + e: + example: AQAB + type: string + kid: + example: 7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345 + type: string + kty: + example: RSA + type: string + "n": + type: string + use: + example: sig + type: string + x: + type: string + type: object + dto.JWKS: + example: + keys: + - kty: RSA + e: AQAB + use: sig + kid: 7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345 + x: x + alg: RS256 + "n": "n" + - kty: RSA + e: AQAB + use: sig + kid: 7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345 + x: x + alg: RS256 + "n": "n" + properties: + keys: + items: + $ref: "#/components/schemas/dto.JWK" + type: array + type: object + dto.LogoutRequest: + properties: + refresh_token: + example: m0l9o8rT3t0V8d3eFf... + type: string + type: object + dto.RefreshRequest: + properties: + refresh_token: + example: m0l9o8rT3t0V8d3eFf... + type: string + type: object + dto.ServerResponse: + example: + hostname: hostname + public_ip_address: public_ip_address + role: role + updated_at: updated_at + ssh_key_id: ssh_key_id + organization_id: organization_id + created_at: created_at + private_ip_address: private_ip_address + id: id + ssh_user: ssh_user + status: status + properties: + created_at: + type: string + hostname: + type: string + id: + type: string + organization_id: + type: string + private_ip_address: + type: string + public_ip_address: + type: string + role: + type: string + ssh_key_id: + type: string + ssh_user: + type: string + status: + type: string + updated_at: + type: string + type: object + dto.SshResponse: + example: + public_key: public_key + updated_at: updated_at + organization_id: organization_id + fingerprint: fingerprint + name: name + created_at: created_at + id: id + properties: + created_at: + type: string + fingerprint: + type: string + id: + type: string + name: + type: string + organization_id: + type: string + public_key: + type: string + updated_at: + type: string + type: object + dto.SshRevealResponse: + example: + public_key: public_key + updated_at: updated_at + organization_id: organization_id + fingerprint: fingerprint + name: name + created_at: created_at + private_key: private_key + id: id + properties: + created_at: + type: string + fingerprint: + type: string + id: + type: string + name: + type: string + organization_id: + type: string + private_key: + type: string + public_key: + type: string + updated_at: + type: string + type: object + dto.TaintResponse: + example: + effect: effect + id: id + value: value + key: key + properties: + effect: + type: string + id: + type: string + key: + type: string + value: + type: string + type: object + dto.TokenPair: + example: + access_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij... + refresh_token: m0l9o8rT3t0V8d3eFf.... + token_type: Bearer + expires_in: 3600 + properties: + access_token: + example: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij... + type: string + expires_in: + example: 3600 + type: integer + refresh_token: + example: m0l9o8rT3t0V8d3eFf.... + type: string + token_type: + example: Bearer + type: string + type: object + dto.UpdateServerRequest: + properties: + hostname: + type: string + private_ip_address: + type: string + public_ip_address: + type: string + role: + example: master|worker|bastion + type: string + ssh_key_id: + type: string + ssh_user: + type: string + status: + example: pending|provisioning|ready|failed + type: string + type: object + dto.UpdateTaintRequest: + properties: + effect: + type: string + key: + type: string + value: + type: string + type: object + handlers.createUserKeyRequest: + properties: + expires_in_hours: + description: optional TTL + type: integer + name: + type: string + type: object + handlers.meResponse: + example: + emails: + - is_primary: true + updated_at: 2000-01-23T04:56:07.000+00:00 + user_id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + created_at: 2000-01-23T04:56:07.000+00:00 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + is_verified: true + user: + avatar_url: avatar_url + updated_at: 2000-01-23T04:56:07.000+00:00 + is_disabled: true + created_at: 2000-01-23T04:56:07.000+00:00 + primary_email: primary_email + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + display_name: display_name + email: email + - is_primary: true + updated_at: 2000-01-23T04:56:07.000+00:00 + user_id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + created_at: 2000-01-23T04:56:07.000+00:00 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + is_verified: true + user: + avatar_url: avatar_url + updated_at: 2000-01-23T04:56:07.000+00:00 + is_disabled: true + created_at: 2000-01-23T04:56:07.000+00:00 + primary_email: primary_email + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + display_name: display_name + email: email + avatar_url: avatar_url + updated_at: 2000-01-23T04:56:07.000+00:00 + is_disabled: true + organizations: + - updated_at: 2000-01-23T04:56:07.000+00:00 + domain: domain + name: name + created_at: 2000-01-23T04:56:07.000+00:00 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + - updated_at: 2000-01-23T04:56:07.000+00:00 + domain: domain + name: name + created_at: 2000-01-23T04:56:07.000+00:00 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + created_at: 2000-01-23T04:56:07.000+00:00 + primary_email: primary_email + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + display_name: display_name + properties: + avatar_url: + type: string + created_at: + format: date-time + type: string + display_name: + type: string + emails: + items: + $ref: "#/components/schemas/models.UserEmail" + type: array + id: + description: "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6" + format: uuid + type: string + is_disabled: + type: boolean + organizations: + items: + $ref: "#/components/schemas/models.Organization" + type: array + primary_email: + type: string + updated_at: + format: date-time + type: string + type: object + handlers.memberOut: + example: + role: role + user_id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + email: email + properties: + email: + type: string + role: + description: owner/admin/member + type: string + user_id: + format: uuid + type: string + type: object + handlers.memberUpsertReq: + properties: + role: + example: member + type: string + user_id: + format: uuid + type: string + type: object + handlers.orgCreateReq: + properties: + domain: + example: acme.com + type: string + name: + example: Acme Corp + type: string + type: object + handlers.orgKeyCreateReq: + properties: + expires_in_hours: + example: 720 + type: integer + name: + example: automation-bot + type: string + type: object + handlers.orgKeyCreateResp: + example: + org_key: org_key + expires_at: expires_at + scope: scope + name: name + created_at: created_at + id: id + org_secret: org_secret + properties: + created_at: + type: string + expires_at: + type: string + id: + type: string + name: + type: string + org_key: + description: "shown once:" + type: string + org_secret: + description: "shown once:" + type: string + scope: + description: '"org"' + type: string + type: object + handlers.orgUpdateReq: + properties: + domain: + type: string + name: + type: string + type: object + handlers.updateMeRequest: + properties: + display_name: + type: string + type: object + handlers.userAPIKeyOut: + example: + last_used_at: last_used_at + expires_at: expires_at + plain: plain + scope: scope + name: name + created_at: created_at + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + properties: + created_at: + type: string + expires_at: + type: string + id: + format: uuid + type: string + last_used_at: + type: string + name: + type: string + plain: + description: "Shown only on create:" + type: string + scope: + description: '"user"' + type: string + type: object + models.APIKey: + example: + last_used_at: 2000-01-23T04:56:07.000+00:00 + expires_at: 2000-01-23T04:56:07.000+00:00 + updated_at: 2000-01-23T04:56:07.000+00:00 + user_id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + org_id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + prefix: prefix + scope: scope + name: name + created_at: 2000-01-23T04:56:07.000+00:00 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + revoked: true + properties: + created_at: + format: date-time + type: string + expires_at: + format: date-time + type: string + id: + format: uuid + type: string + last_used_at: + format: date-time + type: string + name: + type: string + org_id: + format: uuid + type: string + prefix: + type: string + revoked: + type: boolean + scope: + type: string + updated_at: + format: date-time + type: string + user_id: + format: uuid + type: string + type: object + models.Organization: + example: + updated_at: 2000-01-23T04:56:07.000+00:00 + domain: domain + name: name + created_at: 2000-01-23T04:56:07.000+00:00 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + properties: + created_at: + format: date-time + type: string + domain: + type: string + id: + description: "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6" + format: uuid + type: string + name: + type: string + updated_at: + format: date-time + type: string + type: object + models.User: + example: + avatar_url: avatar_url + updated_at: 2000-01-23T04:56:07.000+00:00 + is_disabled: true + created_at: 2000-01-23T04:56:07.000+00:00 + primary_email: primary_email + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + display_name: display_name + properties: + avatar_url: + type: string + created_at: + format: date-time + type: string + display_name: + type: string + id: + description: "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6" + format: uuid + type: string + is_disabled: + type: boolean + primary_email: + type: string + updated_at: + format: date-time + type: string + type: object + models.UserEmail: + example: + is_primary: true + updated_at: 2000-01-23T04:56:07.000+00:00 + user_id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + created_at: 2000-01-23T04:56:07.000+00:00 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + is_verified: true + user: + avatar_url: avatar_url + updated_at: 2000-01-23T04:56:07.000+00:00 + is_disabled: true + created_at: 2000-01-23T04:56:07.000+00:00 + primary_email: primary_email + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + display_name: display_name + email: email + properties: + created_at: + format: date-time + type: string + email: + type: string + id: + description: "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6" + format: uuid + type: string + is_primary: + type: boolean + is_verified: + type: boolean + updated_at: + format: date-time + type: string + user: + $ref: "#/components/schemas/models.User" + user_id: + format: uuid + type: string + type: object + utils.ErrorResponse: + example: + code: code + message: message + properties: + code: + description: |- + A machine-readable error code, e.g. "validation_error" + example: validation_error + type: string + message: + description: |- + Human-readable message + example: slug is required + type: string + type: object + securitySchemes: + ApiKeyAuth: + description: User API key + in: header + name: X-API-KEY + type: apiKey + BearerAuth: + description: Bearer token authentication + in: header + name: Authorization + type: apiKey + OrgKeyAuth: + description: Org-level key/secret authentication + in: header + name: X-ORG-KEY + type: apiKey + OrgSecretAuth: + description: Org-level secret + in: header + name: X-ORG-SECRET + type: apiKey +x-original-swagger-version: "2.0" diff --git a/sdk/go/api_auth.go b/sdk/go/api_auth.go new file mode 100644 index 0000000..1f706b3 --- /dev/null +++ b/sdk/go/api_auth.go @@ -0,0 +1,537 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// AuthAPIService AuthAPI service +type AuthAPIService service + +type ApiAuthCallbackRequest struct { + ctx context.Context + ApiService *AuthAPIService + provider string +} + +func (r ApiAuthCallbackRequest) Execute() (*DtoTokenPair, *http.Response, error) { + return r.ApiService.AuthCallbackExecute(r) +} + +/* +AuthCallback Handle social login callback + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param provider google|github + @return ApiAuthCallbackRequest +*/ +func (a *AuthAPIService) AuthCallback(ctx context.Context, provider string) ApiAuthCallbackRequest { + return ApiAuthCallbackRequest{ + ApiService: a, + ctx: ctx, + provider: provider, + } +} + +// Execute executes the request +// +// @return DtoTokenPair +func (a *AuthAPIService) AuthCallbackExecute(r ApiAuthCallbackRequest) (*DtoTokenPair, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoTokenPair + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "AuthAPIService.AuthCallback") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/auth/{provider}/callback" + localVarPath = strings.Replace(localVarPath, "{"+"provider"+"}", url.PathEscape(parameterValueToString(r.provider, "provider")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiAuthStartRequest struct { + ctx context.Context + ApiService *AuthAPIService + provider string +} + +func (r ApiAuthStartRequest) Execute() (*DtoAuthStartResponse, *http.Response, error) { + return r.ApiService.AuthStartExecute(r) +} + +/* +AuthStart Begin social login + +Returns provider authorization URL for the frontend to redirect + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param provider google|github + @return ApiAuthStartRequest +*/ +func (a *AuthAPIService) AuthStart(ctx context.Context, provider string) ApiAuthStartRequest { + return ApiAuthStartRequest{ + ApiService: a, + ctx: ctx, + provider: provider, + } +} + +// Execute executes the request +// +// @return DtoAuthStartResponse +func (a *AuthAPIService) AuthStartExecute(r ApiAuthStartRequest) (*DtoAuthStartResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoAuthStartResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "AuthAPIService.AuthStart") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/auth/{provider}/start" + localVarPath = strings.Replace(localVarPath, "{"+"provider"+"}", url.PathEscape(parameterValueToString(r.provider, "provider")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetJWKSRequest struct { + ctx context.Context + ApiService *AuthAPIService +} + +func (r ApiGetJWKSRequest) Execute() (*DtoJWKS, *http.Response, error) { + return r.ApiService.GetJWKSExecute(r) +} + +/* +GetJWKS Get JWKS + +Returns the JSON Web Key Set for token verification + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGetJWKSRequest +*/ +func (a *AuthAPIService) GetJWKS(ctx context.Context) ApiGetJWKSRequest { + return ApiGetJWKSRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return DtoJWKS +func (a *AuthAPIService) GetJWKSExecute(r ApiGetJWKSRequest) (*DtoJWKS, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoJWKS + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "AuthAPIService.GetJWKS") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/.well-known/jwks.json" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiLogoutRequest struct { + ctx context.Context + ApiService *AuthAPIService + body *DtoLogoutRequest +} + +// Refresh token +func (r ApiLogoutRequest) Body(body DtoLogoutRequest) ApiLogoutRequest { + r.body = &body + return r +} + +func (r ApiLogoutRequest) Execute() (*http.Response, error) { + return r.ApiService.LogoutExecute(r) +} + +/* +Logout Revoke refresh token family (logout everywhere) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiLogoutRequest +*/ +func (a *AuthAPIService) Logout(ctx context.Context) ApiLogoutRequest { + return ApiLogoutRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +func (a *AuthAPIService) LogoutExecute(r ApiLogoutRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "AuthAPIService.Logout") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/auth/logout" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiRefreshRequest struct { + ctx context.Context + ApiService *AuthAPIService + body *DtoRefreshRequest +} + +// Refresh token +func (r ApiRefreshRequest) Body(body DtoRefreshRequest) ApiRefreshRequest { + r.body = &body + return r +} + +func (r ApiRefreshRequest) Execute() (*DtoTokenPair, *http.Response, error) { + return r.ApiService.RefreshExecute(r) +} + +/* +Refresh Rotate refresh token + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiRefreshRequest +*/ +func (a *AuthAPIService) Refresh(ctx context.Context) ApiRefreshRequest { + return ApiRefreshRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return DtoTokenPair +func (a *AuthAPIService) RefreshExecute(r ApiRefreshRequest) (*DtoTokenPair, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoTokenPair + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "AuthAPIService.Refresh") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/auth/refresh" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/sdk/go/api_me.go b/sdk/go/api_me.go new file mode 100644 index 0000000..71d8769 --- /dev/null +++ b/sdk/go/api_me.go @@ -0,0 +1,286 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" +) + +// MeAPIService MeAPI service +type MeAPIService service + +type ApiGetMeRequest struct { + ctx context.Context + ApiService *MeAPIService +} + +func (r ApiGetMeRequest) Execute() (*HandlersMeResponse, *http.Response, error) { + return r.ApiService.GetMeExecute(r) +} + +/* +GetMe Get current user profile + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGetMeRequest +*/ +func (a *MeAPIService) GetMe(ctx context.Context) ApiGetMeRequest { + return ApiGetMeRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return HandlersMeResponse +func (a *MeAPIService) GetMeExecute(r ApiGetMeRequest) (*HandlersMeResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *HandlersMeResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeAPIService.GetMe") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/me" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["ApiKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-API-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiUpdateMeRequest struct { + ctx context.Context + ApiService *MeAPIService + body *HandlersUpdateMeRequest +} + +// Patch profile +func (r ApiUpdateMeRequest) Body(body HandlersUpdateMeRequest) ApiUpdateMeRequest { + r.body = &body + return r +} + +func (r ApiUpdateMeRequest) Execute() (*ModelsUser, *http.Response, error) { + return r.ApiService.UpdateMeExecute(r) +} + +/* +UpdateMe Update current user profile + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiUpdateMeRequest +*/ +func (a *MeAPIService) UpdateMe(ctx context.Context) ApiUpdateMeRequest { + return ApiUpdateMeRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ModelsUser +func (a *MeAPIService) UpdateMeExecute(r ApiUpdateMeRequest) (*ModelsUser, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelsUser + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeAPIService.UpdateMe") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/me" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["ApiKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-API-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/sdk/go/api_me_api_keys.go b/sdk/go/api_me_api_keys.go new file mode 100644 index 0000000..5b84de3 --- /dev/null +++ b/sdk/go/api_me_api_keys.go @@ -0,0 +1,393 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// MeAPIKeysAPIService MeAPIKeysAPI service +type MeAPIKeysAPIService service + +type ApiCreateUserAPIKeyRequest struct { + ctx context.Context + ApiService *MeAPIKeysAPIService + body *HandlersCreateUserKeyRequest +} + +// Key options +func (r ApiCreateUserAPIKeyRequest) Body(body HandlersCreateUserKeyRequest) ApiCreateUserAPIKeyRequest { + r.body = &body + return r +} + +func (r ApiCreateUserAPIKeyRequest) Execute() (*HandlersUserAPIKeyOut, *http.Response, error) { + return r.ApiService.CreateUserAPIKeyExecute(r) +} + +/* +CreateUserAPIKey Create a new user API key + +Returns the plaintext key once. Store it securely on the client side. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateUserAPIKeyRequest +*/ +func (a *MeAPIKeysAPIService) CreateUserAPIKey(ctx context.Context) ApiCreateUserAPIKeyRequest { + return ApiCreateUserAPIKeyRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return HandlersUserAPIKeyOut +func (a *MeAPIKeysAPIService) CreateUserAPIKeyExecute(r ApiCreateUserAPIKeyRequest) (*HandlersUserAPIKeyOut, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *HandlersUserAPIKeyOut + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeAPIKeysAPIService.CreateUserAPIKey") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/me/api-keys" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["ApiKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-API-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiDeleteUserAPIKeyRequest struct { + ctx context.Context + ApiService *MeAPIKeysAPIService + id string +} + +func (r ApiDeleteUserAPIKeyRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteUserAPIKeyExecute(r) +} + +/* +DeleteUserAPIKey Delete a user API key + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Key ID (UUID) + @return ApiDeleteUserAPIKeyRequest +*/ +func (a *MeAPIKeysAPIService) DeleteUserAPIKey(ctx context.Context, id string) ApiDeleteUserAPIKeyRequest { + return ApiDeleteUserAPIKeyRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +func (a *MeAPIKeysAPIService) DeleteUserAPIKeyExecute(r ApiDeleteUserAPIKeyRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeAPIKeysAPIService.DeleteUserAPIKey") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/me/api-keys/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiListUserAPIKeysRequest struct { + ctx context.Context + ApiService *MeAPIKeysAPIService +} + +func (r ApiListUserAPIKeysRequest) Execute() ([]HandlersUserAPIKeyOut, *http.Response, error) { + return r.ApiService.ListUserAPIKeysExecute(r) +} + +/* +ListUserAPIKeys List my API keys + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiListUserAPIKeysRequest +*/ +func (a *MeAPIKeysAPIService) ListUserAPIKeys(ctx context.Context) ApiListUserAPIKeysRequest { + return ApiListUserAPIKeysRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return []HandlersUserAPIKeyOut +func (a *MeAPIKeysAPIService) ListUserAPIKeysExecute(r ApiListUserAPIKeysRequest) ([]HandlersUserAPIKeyOut, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []HandlersUserAPIKeyOut + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeAPIKeysAPIService.ListUserAPIKeys") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/me/api-keys" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["ApiKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-API-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/sdk/go/api_orgs.go b/sdk/go/api_orgs.go new file mode 100644 index 0000000..6e97fcb --- /dev/null +++ b/sdk/go/api_orgs.go @@ -0,0 +1,1476 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// OrgsAPIService OrgsAPI service +type OrgsAPIService service + +type ApiAddOrUpdateMemberRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string + body *HandlersMemberUpsertReq +} + +// User & role +func (r ApiAddOrUpdateMemberRequest) Body(body HandlersMemberUpsertReq) ApiAddOrUpdateMemberRequest { + r.body = &body + return r +} + +func (r ApiAddOrUpdateMemberRequest) Execute() (*HandlersMemberOut, *http.Response, error) { + return r.ApiService.AddOrUpdateMemberExecute(r) +} + +/* +AddOrUpdateMember Add or update a member (owner/admin) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @return ApiAddOrUpdateMemberRequest +*/ +func (a *OrgsAPIService) AddOrUpdateMember(ctx context.Context, id string) ApiAddOrUpdateMemberRequest { + return ApiAddOrUpdateMemberRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return HandlersMemberOut +func (a *OrgsAPIService) AddOrUpdateMemberExecute(r ApiAddOrUpdateMemberRequest) (*HandlersMemberOut, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *HandlersMemberOut + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.AddOrUpdateMember") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}/members" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateOrgRequest struct { + ctx context.Context + ApiService *OrgsAPIService + body *HandlersOrgCreateReq +} + +// Org payload +func (r ApiCreateOrgRequest) Body(body HandlersOrgCreateReq) ApiCreateOrgRequest { + r.body = &body + return r +} + +func (r ApiCreateOrgRequest) Execute() (*ModelsOrganization, *http.Response, error) { + return r.ApiService.CreateOrgExecute(r) +} + +/* +CreateOrg Create organization + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateOrgRequest +*/ +func (a *OrgsAPIService) CreateOrg(ctx context.Context) ApiCreateOrgRequest { + return ApiCreateOrgRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ModelsOrganization +func (a *OrgsAPIService) CreateOrgExecute(r ApiCreateOrgRequest) (*ModelsOrganization, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelsOrganization + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.CreateOrg") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 409 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateOrgKeyRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string + body *HandlersOrgKeyCreateReq +} + +// Key name + optional expiry +func (r ApiCreateOrgKeyRequest) Body(body HandlersOrgKeyCreateReq) ApiCreateOrgKeyRequest { + r.body = &body + return r +} + +func (r ApiCreateOrgKeyRequest) Execute() (*HandlersOrgKeyCreateResp, *http.Response, error) { + return r.ApiService.CreateOrgKeyExecute(r) +} + +/* +CreateOrgKey Create org key/secret pair (owner/admin) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @return ApiCreateOrgKeyRequest +*/ +func (a *OrgsAPIService) CreateOrgKey(ctx context.Context, id string) ApiCreateOrgKeyRequest { + return ApiCreateOrgKeyRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return HandlersOrgKeyCreateResp +func (a *OrgsAPIService) CreateOrgKeyExecute(r ApiCreateOrgKeyRequest) (*HandlersOrgKeyCreateResp, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *HandlersOrgKeyCreateResp + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.CreateOrgKey") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}/api-keys" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiDeleteOrgRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string +} + +func (r ApiDeleteOrgRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteOrgExecute(r) +} + +/* +DeleteOrg Delete organization (owner) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @return ApiDeleteOrgRequest +*/ +func (a *OrgsAPIService) DeleteOrg(ctx context.Context, id string) ApiDeleteOrgRequest { + return ApiDeleteOrgRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +func (a *OrgsAPIService) DeleteOrgExecute(r ApiDeleteOrgRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.DeleteOrg") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiDeleteOrgKeyRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string + keyId string +} + +func (r ApiDeleteOrgKeyRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteOrgKeyExecute(r) +} + +/* +DeleteOrgKey Delete org key (owner/admin) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @param keyId Key ID (UUID) + @return ApiDeleteOrgKeyRequest +*/ +func (a *OrgsAPIService) DeleteOrgKey(ctx context.Context, id string, keyId string) ApiDeleteOrgKeyRequest { + return ApiDeleteOrgKeyRequest{ + ApiService: a, + ctx: ctx, + id: id, + keyId: keyId, + } +} + +// Execute executes the request +func (a *OrgsAPIService) DeleteOrgKeyExecute(r ApiDeleteOrgKeyRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.DeleteOrgKey") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}/api-keys/{key_id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"key_id"+"}", url.PathEscape(parameterValueToString(r.keyId, "keyId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiGetOrgRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string +} + +func (r ApiGetOrgRequest) Execute() (*ModelsOrganization, *http.Response, error) { + return r.ApiService.GetOrgExecute(r) +} + +/* +GetOrg Get organization + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @return ApiGetOrgRequest +*/ +func (a *OrgsAPIService) GetOrg(ctx context.Context, id string) ApiGetOrgRequest { + return ApiGetOrgRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return ModelsOrganization +func (a *OrgsAPIService) GetOrgExecute(r ApiGetOrgRequest) (*ModelsOrganization, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelsOrganization + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.GetOrg") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListMembersRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string +} + +func (r ApiListMembersRequest) Execute() ([]HandlersMemberOut, *http.Response, error) { + return r.ApiService.ListMembersExecute(r) +} + +/* +ListMembers List members in org + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @return ApiListMembersRequest +*/ +func (a *OrgsAPIService) ListMembers(ctx context.Context, id string) ApiListMembersRequest { + return ApiListMembersRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return []HandlersMemberOut +func (a *OrgsAPIService) ListMembersExecute(r ApiListMembersRequest) ([]HandlersMemberOut, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []HandlersMemberOut + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.ListMembers") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}/members" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListMyOrgsRequest struct { + ctx context.Context + ApiService *OrgsAPIService +} + +func (r ApiListMyOrgsRequest) Execute() ([]ModelsOrganization, *http.Response, error) { + return r.ApiService.ListMyOrgsExecute(r) +} + +/* +ListMyOrgs List organizations I belong to + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiListMyOrgsRequest +*/ +func (a *OrgsAPIService) ListMyOrgs(ctx context.Context) ApiListMyOrgsRequest { + return ApiListMyOrgsRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return []ModelsOrganization +func (a *OrgsAPIService) ListMyOrgsExecute(r ApiListMyOrgsRequest) ([]ModelsOrganization, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []ModelsOrganization + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.ListMyOrgs") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListOrgKeysRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string +} + +func (r ApiListOrgKeysRequest) Execute() ([]ModelsAPIKey, *http.Response, error) { + return r.ApiService.ListOrgKeysExecute(r) +} + +/* +ListOrgKeys List org-scoped API keys (no secrets) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @return ApiListOrgKeysRequest +*/ +func (a *OrgsAPIService) ListOrgKeys(ctx context.Context, id string) ApiListOrgKeysRequest { + return ApiListOrgKeysRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return []ModelsAPIKey +func (a *OrgsAPIService) ListOrgKeysExecute(r ApiListOrgKeysRequest) ([]ModelsAPIKey, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []ModelsAPIKey + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.ListOrgKeys") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}/api-keys" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiRemoveMemberRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string + userId string +} + +func (r ApiRemoveMemberRequest) Execute() (*http.Response, error) { + return r.ApiService.RemoveMemberExecute(r) +} + +/* +RemoveMember Remove a member (owner/admin) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @param userId User ID (UUID) + @return ApiRemoveMemberRequest +*/ +func (a *OrgsAPIService) RemoveMember(ctx context.Context, id string, userId string) ApiRemoveMemberRequest { + return ApiRemoveMemberRequest{ + ApiService: a, + ctx: ctx, + id: id, + userId: userId, + } +} + +// Execute executes the request +func (a *OrgsAPIService) RemoveMemberExecute(r ApiRemoveMemberRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.RemoveMember") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}/members/{user_id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"user_id"+"}", url.PathEscape(parameterValueToString(r.userId, "userId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiUpdateOrgRequest struct { + ctx context.Context + ApiService *OrgsAPIService + id string + body *HandlersOrgUpdateReq +} + +// Update payload +func (r ApiUpdateOrgRequest) Body(body HandlersOrgUpdateReq) ApiUpdateOrgRequest { + r.body = &body + return r +} + +func (r ApiUpdateOrgRequest) Execute() (*ModelsOrganization, *http.Response, error) { + return r.ApiService.UpdateOrgExecute(r) +} + +/* +UpdateOrg Update organization (owner/admin) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Org ID (UUID) + @return ApiUpdateOrgRequest +*/ +func (a *OrgsAPIService) UpdateOrg(ctx context.Context, id string) ApiUpdateOrgRequest { + return ApiUpdateOrgRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return ModelsOrganization +func (a *OrgsAPIService) UpdateOrgExecute(r ApiUpdateOrgRequest) (*ModelsOrganization, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelsOrganization + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrgsAPIService.UpdateOrg") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/orgs/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v UtilsErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/sdk/go/api_servers.go b/sdk/go/api_servers.go new file mode 100644 index 0000000..7bdb5c9 --- /dev/null +++ b/sdk/go/api_servers.go @@ -0,0 +1,1065 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// ServersAPIService ServersAPI service +type ServersAPIService service + +type ApiCreateServerRequest struct { + ctx context.Context + ApiService *ServersAPIService + body *DtoCreateServerRequest + xOrgID *string +} + +// Server payload +func (r ApiCreateServerRequest) Body(body DtoCreateServerRequest) ApiCreateServerRequest { + r.body = &body + return r +} + +// Organization UUID +func (r ApiCreateServerRequest) XOrgID(xOrgID string) ApiCreateServerRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiCreateServerRequest) Execute() (*DtoServerResponse, *http.Response, error) { + return r.ApiService.CreateServerExecute(r) +} + +/* +CreateServer Create server (org scoped) + +Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateServerRequest +*/ +func (a *ServersAPIService) CreateServer(ctx context.Context) ApiCreateServerRequest { + return ApiCreateServerRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return DtoServerResponse +func (a *ServersAPIService) CreateServerExecute(r ApiCreateServerRequest) (*DtoServerResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoServerResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServersAPIService.CreateServer") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/servers" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiDeleteServerRequest struct { + ctx context.Context + ApiService *ServersAPIService + id string + xOrgID *string +} + +// Organization UUID +func (r ApiDeleteServerRequest) XOrgID(xOrgID string) ApiDeleteServerRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiDeleteServerRequest) Execute() (string, *http.Response, error) { + return r.ApiService.DeleteServerExecute(r) +} + +/* +DeleteServer Delete server (org scoped) + +Permanently deletes the server. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Server ID (UUID) + @return ApiDeleteServerRequest +*/ +func (a *ServersAPIService) DeleteServer(ctx context.Context, id string) ApiDeleteServerRequest { + return ApiDeleteServerRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return string +func (a *ServersAPIService) DeleteServerExecute(r ApiDeleteServerRequest) (string, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue string + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServersAPIService.DeleteServer") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/servers/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetServerRequest struct { + ctx context.Context + ApiService *ServersAPIService + id string + xOrgID *string +} + +// Organization UUID +func (r ApiGetServerRequest) XOrgID(xOrgID string) ApiGetServerRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiGetServerRequest) Execute() (*DtoServerResponse, *http.Response, error) { + return r.ApiService.GetServerExecute(r) +} + +/* +GetServer Get server by ID (org scoped) + +Returns one server in the given organization. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Server ID (UUID) + @return ApiGetServerRequest +*/ +func (a *ServersAPIService) GetServer(ctx context.Context, id string) ApiGetServerRequest { + return ApiGetServerRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return DtoServerResponse +func (a *ServersAPIService) GetServerExecute(r ApiGetServerRequest) (*DtoServerResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoServerResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServersAPIService.GetServer") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/servers/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListServersRequest struct { + ctx context.Context + ApiService *ServersAPIService + xOrgID *string + status *string + role *string +} + +// Organization UUID +func (r ApiListServersRequest) XOrgID(xOrgID string) ApiListServersRequest { + r.xOrgID = &xOrgID + return r +} + +// Filter by status (pending|provisioning|ready|failed) +func (r ApiListServersRequest) Status(status string) ApiListServersRequest { + r.status = &status + return r +} + +// Filter by role +func (r ApiListServersRequest) Role(role string) ApiListServersRequest { + r.role = &role + return r +} + +func (r ApiListServersRequest) Execute() ([]DtoServerResponse, *http.Response, error) { + return r.ApiService.ListServersExecute(r) +} + +/* +ListServers List servers (org scoped) + +Returns servers for the organization in X-Org-ID. Optional filters: status, role. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiListServersRequest +*/ +func (a *ServersAPIService) ListServers(ctx context.Context) ApiListServersRequest { + return ApiListServersRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return []DtoServerResponse +func (a *ServersAPIService) ListServersExecute(r ApiListServersRequest) ([]DtoServerResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []DtoServerResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServersAPIService.ListServers") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/servers" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.status != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "status", r.status, "", "") + } + if r.role != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "role", r.role, "", "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiUpdateServerRequest struct { + ctx context.Context + ApiService *ServersAPIService + id string + body *DtoUpdateServerRequest + xOrgID *string +} + +// Fields to update +func (r ApiUpdateServerRequest) Body(body DtoUpdateServerRequest) ApiUpdateServerRequest { + r.body = &body + return r +} + +// Organization UUID +func (r ApiUpdateServerRequest) XOrgID(xOrgID string) ApiUpdateServerRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiUpdateServerRequest) Execute() (*DtoServerResponse, *http.Response, error) { + return r.ApiService.UpdateServerExecute(r) +} + +/* +UpdateServer Update server (org scoped) + +Partially update fields; changing ssh_key_id validates ownership. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Server ID (UUID) + @return ApiUpdateServerRequest +*/ +func (a *ServersAPIService) UpdateServer(ctx context.Context, id string) ApiUpdateServerRequest { + return ApiUpdateServerRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return DtoServerResponse +func (a *ServersAPIService) UpdateServerExecute(r ApiUpdateServerRequest) (*DtoServerResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoServerResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServersAPIService.UpdateServer") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/servers/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/sdk/go/api_ssh.go b/sdk/go/api_ssh.go new file mode 100644 index 0000000..1d37090 --- /dev/null +++ b/sdk/go/api_ssh.go @@ -0,0 +1,1055 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// SshAPIService SshAPI service +type SshAPIService service + +type ApiCreateSSHKeyRequest struct { + ctx context.Context + ApiService *SshAPIService + body *DtoCreateSSHRequest + xOrgID *string +} + +// Key generation options +func (r ApiCreateSSHKeyRequest) Body(body DtoCreateSSHRequest) ApiCreateSSHKeyRequest { + r.body = &body + return r +} + +// Organization UUID +func (r ApiCreateSSHKeyRequest) XOrgID(xOrgID string) ApiCreateSSHKeyRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiCreateSSHKeyRequest) Execute() (*DtoSshResponse, *http.Response, error) { + return r.ApiService.CreateSSHKeyExecute(r) +} + +/* +CreateSSHKey Create ssh keypair (org scoped) + +Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateSSHKeyRequest +*/ +func (a *SshAPIService) CreateSSHKey(ctx context.Context) ApiCreateSSHKeyRequest { + return ApiCreateSSHKeyRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return DtoSshResponse +func (a *SshAPIService) CreateSSHKeyExecute(r ApiCreateSSHKeyRequest) (*DtoSshResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoSshResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SshAPIService.CreateSSHKey") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/ssh" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiDeleteSSHKeyRequest struct { + ctx context.Context + ApiService *SshAPIService + id string + xOrgID *string +} + +// Organization UUID +func (r ApiDeleteSSHKeyRequest) XOrgID(xOrgID string) ApiDeleteSSHKeyRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiDeleteSSHKeyRequest) Execute() (string, *http.Response, error) { + return r.ApiService.DeleteSSHKeyExecute(r) +} + +/* +DeleteSSHKey Delete ssh keypair (org scoped) + +Permanently deletes a keypair. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id SSH Key ID (UUID) + @return ApiDeleteSSHKeyRequest +*/ +func (a *SshAPIService) DeleteSSHKey(ctx context.Context, id string) ApiDeleteSSHKeyRequest { + return ApiDeleteSSHKeyRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return string +func (a *SshAPIService) DeleteSSHKeyExecute(r ApiDeleteSSHKeyRequest) (string, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue string + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SshAPIService.DeleteSSHKey") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/ssh/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiDownloadSSHKeyRequest struct { + ctx context.Context + ApiService *SshAPIService + xOrgID *string + id string + part *string +} + +// Organization UUID +func (r ApiDownloadSSHKeyRequest) XOrgID(xOrgID string) ApiDownloadSSHKeyRequest { + r.xOrgID = &xOrgID + return r +} + +// Which part to download +func (r ApiDownloadSSHKeyRequest) Part(part string) ApiDownloadSSHKeyRequest { + r.part = &part + return r +} + +func (r ApiDownloadSSHKeyRequest) Execute() (string, *http.Response, error) { + return r.ApiService.DownloadSSHKeyExecute(r) +} + +/* +DownloadSSHKey Download ssh key files by ID (org scoped) + +Download `part=public|private|both` of the keypair. `both` returns a zip file. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id SSH Key ID (UUID) + @return ApiDownloadSSHKeyRequest +*/ +func (a *SshAPIService) DownloadSSHKey(ctx context.Context, id string) ApiDownloadSSHKeyRequest { + return ApiDownloadSSHKeyRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return string +func (a *SshAPIService) DownloadSSHKeyExecute(r ApiDownloadSSHKeyRequest) (string, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue string + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SshAPIService.DownloadSSHKey") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/ssh/{id}/download" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.xOrgID == nil { + return localVarReturnValue, nil, reportError("xOrgID is required and must be specified") + } + if r.part == nil { + return localVarReturnValue, nil, reportError("part is required and must be specified") + } + + parameterAddToHeaderOrQuery(localVarQueryParams, "part", r.part, "", "") + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetSSHKeyRequest struct { + ctx context.Context + ApiService *SshAPIService + id string + xOrgID *string + reveal *bool +} + +// Organization UUID +func (r ApiGetSSHKeyRequest) XOrgID(xOrgID string) ApiGetSSHKeyRequest { + r.xOrgID = &xOrgID + return r +} + +// Reveal private key PEM +func (r ApiGetSSHKeyRequest) Reveal(reveal bool) ApiGetSSHKeyRequest { + r.reveal = &reveal + return r +} + +func (r ApiGetSSHKeyRequest) Execute() (*DtoSshRevealResponse, *http.Response, error) { + return r.ApiService.GetSSHKeyExecute(r) +} + +/* +GetSSHKey Get ssh key by ID (org scoped) + +Returns public key fields. Append `?reveal=true` to include the private key PEM. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id SSH Key ID (UUID) + @return ApiGetSSHKeyRequest +*/ +func (a *SshAPIService) GetSSHKey(ctx context.Context, id string) ApiGetSSHKeyRequest { + return ApiGetSSHKeyRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return DtoSshRevealResponse +func (a *SshAPIService) GetSSHKeyExecute(r ApiGetSSHKeyRequest) (*DtoSshRevealResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoSshRevealResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SshAPIService.GetSSHKey") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/ssh/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.reveal != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "reveal", r.reveal, "", "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListPublicSshKeysRequest struct { + ctx context.Context + ApiService *SshAPIService + xOrgID *string +} + +// Organization UUID +func (r ApiListPublicSshKeysRequest) XOrgID(xOrgID string) ApiListPublicSshKeysRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiListPublicSshKeysRequest) Execute() ([]DtoSshResponse, *http.Response, error) { + return r.ApiService.ListPublicSshKeysExecute(r) +} + +/* +ListPublicSshKeys List ssh keys (org scoped) + +Returns ssh keys for the organization in X-Org-ID. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiListPublicSshKeysRequest +*/ +func (a *SshAPIService) ListPublicSshKeys(ctx context.Context) ApiListPublicSshKeysRequest { + return ApiListPublicSshKeysRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return []DtoSshResponse +func (a *SshAPIService) ListPublicSshKeysExecute(r ApiListPublicSshKeysRequest) ([]DtoSshResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []DtoSshResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SshAPIService.ListPublicSshKeys") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/ssh" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/sdk/go/api_taints.go b/sdk/go/api_taints.go new file mode 100644 index 0000000..2190b8d --- /dev/null +++ b/sdk/go/api_taints.go @@ -0,0 +1,1073 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// TaintsAPIService TaintsAPI service +type TaintsAPIService service + +type ApiCreateTaintRequest struct { + ctx context.Context + ApiService *TaintsAPIService + body *DtoCreateTaintRequest + xOrgID *string +} + +// Taint payload +func (r ApiCreateTaintRequest) Body(body DtoCreateTaintRequest) ApiCreateTaintRequest { + r.body = &body + return r +} + +// Organization UUID +func (r ApiCreateTaintRequest) XOrgID(xOrgID string) ApiCreateTaintRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiCreateTaintRequest) Execute() (*DtoTaintResponse, *http.Response, error) { + return r.ApiService.CreateTaintExecute(r) +} + +/* +CreateTaint Create node taint (org scoped) + +Creates a taint. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateTaintRequest +*/ +func (a *TaintsAPIService) CreateTaint(ctx context.Context) ApiCreateTaintRequest { + return ApiCreateTaintRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return DtoTaintResponse +func (a *TaintsAPIService) CreateTaintExecute(r ApiCreateTaintRequest) (*DtoTaintResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoTaintResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TaintsAPIService.CreateTaint") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/taints" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiDeleteTaintRequest struct { + ctx context.Context + ApiService *TaintsAPIService + id string + xOrgID *string +} + +// Organization UUID +func (r ApiDeleteTaintRequest) XOrgID(xOrgID string) ApiDeleteTaintRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiDeleteTaintRequest) Execute() (string, *http.Response, error) { + return r.ApiService.DeleteTaintExecute(r) +} + +/* +DeleteTaint Delete taint (org scoped) + +Permanently deletes the taint. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Node Taint ID (UUID) + @return ApiDeleteTaintRequest +*/ +func (a *TaintsAPIService) DeleteTaint(ctx context.Context, id string) ApiDeleteTaintRequest { + return ApiDeleteTaintRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return string +func (a *TaintsAPIService) DeleteTaintExecute(r ApiDeleteTaintRequest) (string, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue string + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TaintsAPIService.DeleteTaint") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/taints/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetTaintRequest struct { + ctx context.Context + ApiService *TaintsAPIService + id string + xOrgID *string +} + +// Organization UUID +func (r ApiGetTaintRequest) XOrgID(xOrgID string) ApiGetTaintRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiGetTaintRequest) Execute() (*DtoTaintResponse, *http.Response, error) { + return r.ApiService.GetTaintExecute(r) +} + +/* +GetTaint Get node taint by ID (org scoped) + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Node Taint ID (UUID) + @return ApiGetTaintRequest +*/ +func (a *TaintsAPIService) GetTaint(ctx context.Context, id string) ApiGetTaintRequest { + return ApiGetTaintRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return DtoTaintResponse +func (a *TaintsAPIService) GetTaintExecute(r ApiGetTaintRequest) (*DtoTaintResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoTaintResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TaintsAPIService.GetTaint") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/taints/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListTaintsRequest struct { + ctx context.Context + ApiService *TaintsAPIService + xOrgID *string + key *string + value *string + q *string +} + +// Organization UUID +func (r ApiListTaintsRequest) XOrgID(xOrgID string) ApiListTaintsRequest { + r.xOrgID = &xOrgID + return r +} + +// Exact key +func (r ApiListTaintsRequest) Key(key string) ApiListTaintsRequest { + r.key = &key + return r +} + +// Exact value +func (r ApiListTaintsRequest) Value(value string) ApiListTaintsRequest { + r.value = &value + return r +} + +// key contains (case-insensitive) +func (r ApiListTaintsRequest) Q(q string) ApiListTaintsRequest { + r.q = &q + return r +} + +func (r ApiListTaintsRequest) Execute() ([]DtoTaintResponse, *http.Response, error) { + return r.ApiService.ListTaintsExecute(r) +} + +/* +ListTaints List node pool taints (org scoped) + +Returns node taints for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiListTaintsRequest +*/ +func (a *TaintsAPIService) ListTaints(ctx context.Context) ApiListTaintsRequest { + return ApiListTaintsRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return []DtoTaintResponse +func (a *TaintsAPIService) ListTaintsExecute(r ApiListTaintsRequest) ([]DtoTaintResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []DtoTaintResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TaintsAPIService.ListTaints") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/taints" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.key != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "key", r.key, "", "") + } + if r.value != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "value", r.value, "", "") + } + if r.q != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "q", r.q, "", "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiUpdateTaintRequest struct { + ctx context.Context + ApiService *TaintsAPIService + id string + body *DtoUpdateTaintRequest + xOrgID *string +} + +// Fields to update +func (r ApiUpdateTaintRequest) Body(body DtoUpdateTaintRequest) ApiUpdateTaintRequest { + r.body = &body + return r +} + +// Organization UUID +func (r ApiUpdateTaintRequest) XOrgID(xOrgID string) ApiUpdateTaintRequest { + r.xOrgID = &xOrgID + return r +} + +func (r ApiUpdateTaintRequest) Execute() (*DtoTaintResponse, *http.Response, error) { + return r.ApiService.UpdateTaintExecute(r) +} + +/* +UpdateTaint Update node taint (org scoped) + +Partially update taint fields. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id Node Taint ID (UUID) + @return ApiUpdateTaintRequest +*/ +func (a *TaintsAPIService) UpdateTaint(ctx context.Context, id string) ApiUpdateTaintRequest { + return ApiUpdateTaintRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// +// @return DtoTaintResponse +func (a *TaintsAPIService) UpdateTaintExecute(r ApiUpdateTaintRequest) (*DtoTaintResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DtoTaintResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TaintsAPIService.UpdateTaint") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/taints/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.xOrgID != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "X-Org-ID", r.xOrgID, "", "") + } + // body params + localVarPostBody = r.body + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgKeyAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-KEY"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["OrgSecretAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["X-ORG-SECRET"] = key + } + } + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 403 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v string + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/sdk/go/client.go b/sdk/go/client.go new file mode 100644 index 0000000..dc0c0c6 --- /dev/null +++ b/sdk/go/client.go @@ -0,0 +1,673 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "log" + "mime/multipart" + "net/http" + "net/http/httputil" + "net/url" + "os" + "path/filepath" + "reflect" + "regexp" + "strconv" + "strings" + "time" + "unicode/utf8" +) + +var ( + JsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\+)?json)`) + XmlCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\+)?xml)`) + queryParamSplit = regexp.MustCompile(`(^|&)([^&]+)`) + queryDescape = strings.NewReplacer("%5B", "[", "%5D", "]") +) + +// APIClient manages communication with the AutoGlue API API v1.0 +// In most cases there should be only one, shared, APIClient. +type APIClient struct { + cfg *Configuration + common service // Reuse a single struct instead of allocating one for each service on the heap. + + // API Services + + AuthAPI *AuthAPIService + + MeAPI *MeAPIService + + MeAPIKeysAPI *MeAPIKeysAPIService + + OrgsAPI *OrgsAPIService + + ServersAPI *ServersAPIService + + SshAPI *SshAPIService + + TaintsAPI *TaintsAPIService +} + +type service struct { + client *APIClient +} + +// NewAPIClient creates a new API client. Requires a userAgent string describing your application. +// optionally a custom http.Client to allow for advanced features such as caching. +func NewAPIClient(cfg *Configuration) *APIClient { + if cfg.HTTPClient == nil { + cfg.HTTPClient = http.DefaultClient + } + + c := &APIClient{} + c.cfg = cfg + c.common.client = c + + // API Services + c.AuthAPI = (*AuthAPIService)(&c.common) + c.MeAPI = (*MeAPIService)(&c.common) + c.MeAPIKeysAPI = (*MeAPIKeysAPIService)(&c.common) + c.OrgsAPI = (*OrgsAPIService)(&c.common) + c.ServersAPI = (*ServersAPIService)(&c.common) + c.SshAPI = (*SshAPIService)(&c.common) + c.TaintsAPI = (*TaintsAPIService)(&c.common) + + return c +} + +func atoi(in string) (int, error) { + return strconv.Atoi(in) +} + +// selectHeaderContentType select a content type from the available list. +func selectHeaderContentType(contentTypes []string) string { + if len(contentTypes) == 0 { + return "" + } + if contains(contentTypes, "application/json") { + return "application/json" + } + return contentTypes[0] // use the first content type specified in 'consumes' +} + +// selectHeaderAccept join all accept types and return +func selectHeaderAccept(accepts []string) string { + if len(accepts) == 0 { + return "" + } + + if contains(accepts, "application/json") { + return "application/json" + } + + return strings.Join(accepts, ",") +} + +// contains is a case insensitive match, finding needle in a haystack +func contains(haystack []string, needle string) bool { + for _, a := range haystack { + if strings.EqualFold(a, needle) { + return true + } + } + return false +} + +// Verify optional parameters are of the correct type. +func typeCheckParameter(obj interface{}, expected string, name string) error { + // Make sure there is an object. + if obj == nil { + return nil + } + + // Check the type is as expected. + if reflect.TypeOf(obj).String() != expected { + return fmt.Errorf("expected %s to be of type %s but received %s", name, expected, reflect.TypeOf(obj).String()) + } + return nil +} + +func parameterValueToString(obj interface{}, key string) string { + if reflect.TypeOf(obj).Kind() != reflect.Ptr { + if actualObj, ok := obj.(interface{ GetActualInstanceValue() interface{} }); ok { + return fmt.Sprintf("%v", actualObj.GetActualInstanceValue()) + } + + return fmt.Sprintf("%v", obj) + } + var param, ok = obj.(MappedNullable) + if !ok { + return "" + } + dataMap, err := param.ToMap() + if err != nil { + return "" + } + return fmt.Sprintf("%v", dataMap[key]) +} + +// parameterAddToHeaderOrQuery adds the provided object to the request header or url query +// supporting deep object syntax +func parameterAddToHeaderOrQuery(headerOrQueryParams interface{}, keyPrefix string, obj interface{}, style string, collectionType string) { + var v = reflect.ValueOf(obj) + var value = "" + if v == reflect.ValueOf(nil) { + value = "null" + } else { + switch v.Kind() { + case reflect.Invalid: + value = "invalid" + + case reflect.Struct: + if t, ok := obj.(MappedNullable); ok { + dataMap, err := t.ToMap() + if err != nil { + return + } + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, dataMap, style, collectionType) + return + } + if t, ok := obj.(time.Time); ok { + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, t.Format(time.RFC3339Nano), style, collectionType) + return + } + value = v.Type().String() + " value" + case reflect.Slice: + var indValue = reflect.ValueOf(obj) + if indValue == reflect.ValueOf(nil) { + return + } + var lenIndValue = indValue.Len() + for i := 0; i < lenIndValue; i++ { + var arrayValue = indValue.Index(i) + var keyPrefixForCollectionType = keyPrefix + if style == "deepObject" { + keyPrefixForCollectionType = keyPrefix + "[" + strconv.Itoa(i) + "]" + } + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefixForCollectionType, arrayValue.Interface(), style, collectionType) + } + return + + case reflect.Map: + var indValue = reflect.ValueOf(obj) + if indValue == reflect.ValueOf(nil) { + return + } + iter := indValue.MapRange() + for iter.Next() { + k, v := iter.Key(), iter.Value() + parameterAddToHeaderOrQuery(headerOrQueryParams, fmt.Sprintf("%s[%s]", keyPrefix, k.String()), v.Interface(), style, collectionType) + } + return + + case reflect.Interface: + fallthrough + case reflect.Ptr: + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, v.Elem().Interface(), style, collectionType) + return + + case reflect.Int, reflect.Int8, reflect.Int16, + reflect.Int32, reflect.Int64: + value = strconv.FormatInt(v.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, + reflect.Uint32, reflect.Uint64, reflect.Uintptr: + value = strconv.FormatUint(v.Uint(), 10) + case reflect.Float32, reflect.Float64: + value = strconv.FormatFloat(v.Float(), 'g', -1, 32) + case reflect.Bool: + value = strconv.FormatBool(v.Bool()) + case reflect.String: + value = v.String() + default: + value = v.Type().String() + " value" + } + } + + switch valuesMap := headerOrQueryParams.(type) { + case url.Values: + if collectionType == "csv" && valuesMap.Get(keyPrefix) != "" { + valuesMap.Set(keyPrefix, valuesMap.Get(keyPrefix)+","+value) + } else { + valuesMap.Add(keyPrefix, value) + } + break + case map[string]string: + valuesMap[keyPrefix] = value + break + } +} + +// helper for converting interface{} parameters to json strings +func parameterToJson(obj interface{}) (string, error) { + jsonBuf, err := json.Marshal(obj) + if err != nil { + return "", err + } + return string(jsonBuf), err +} + +// callAPI do the request. +func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) { + if c.cfg.Debug { + dump, err := httputil.DumpRequestOut(request, true) + if err != nil { + return nil, err + } + log.Printf("\n%s\n", string(dump)) + } + + resp, err := c.cfg.HTTPClient.Do(request) + if err != nil { + return resp, err + } + + if c.cfg.Debug { + dump, err := httputil.DumpResponse(resp, true) + if err != nil { + return resp, err + } + log.Printf("\n%s\n", string(dump)) + } + return resp, err +} + +// Allow modification of underlying config for alternate implementations and testing +// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior +func (c *APIClient) GetConfig() *Configuration { + return c.cfg +} + +type formFile struct { + fileBytes []byte + fileName string + formFileName string +} + +// prepareRequest build the request +func (c *APIClient) prepareRequest( + ctx context.Context, + path string, method string, + postBody interface{}, + headerParams map[string]string, + queryParams url.Values, + formParams url.Values, + formFiles []formFile) (localVarRequest *http.Request, err error) { + + var body *bytes.Buffer + + // Detect postBody type and post. + if postBody != nil { + contentType := headerParams["Content-Type"] + if contentType == "" { + contentType = detectContentType(postBody) + headerParams["Content-Type"] = contentType + } + + body, err = setBody(postBody, contentType) + if err != nil { + return nil, err + } + } + + // add form parameters and file if available. + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(formFiles) > 0) { + if body != nil { + return nil, errors.New("Cannot specify postBody and multipart form at the same time.") + } + body = &bytes.Buffer{} + w := multipart.NewWriter(body) + + for k, v := range formParams { + for _, iv := range v { + if strings.HasPrefix(k, "@") { // file + err = addFile(w, k[1:], iv) + if err != nil { + return nil, err + } + } else { // form value + w.WriteField(k, iv) + } + } + } + for _, formFile := range formFiles { + if len(formFile.fileBytes) > 0 && formFile.fileName != "" { + w.Boundary() + part, err := w.CreateFormFile(formFile.formFileName, filepath.Base(formFile.fileName)) + if err != nil { + return nil, err + } + _, err = part.Write(formFile.fileBytes) + if err != nil { + return nil, err + } + } + } + + // Set the Boundary in the Content-Type + headerParams["Content-Type"] = w.FormDataContentType() + + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + w.Close() + } + + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + + // Setup path and query parameters + url, err := url.Parse(path) + if err != nil { + return nil, err + } + + // Override request host, if applicable + if c.cfg.Host != "" { + url.Host = c.cfg.Host + } + + // Override request scheme, if applicable + if c.cfg.Scheme != "" { + url.Scheme = c.cfg.Scheme + } + + // Adding Query Param + query := url.Query() + for k, v := range queryParams { + for _, iv := range v { + query.Add(k, iv) + } + } + + // Encode the parameters. + url.RawQuery = queryParamSplit.ReplaceAllStringFunc(query.Encode(), func(s string) string { + pieces := strings.Split(s, "=") + pieces[0] = queryDescape.Replace(pieces[0]) + return strings.Join(pieces, "=") + }) + + // Generate a new request + if body != nil { + localVarRequest, err = http.NewRequest(method, url.String(), body) + } else { + localVarRequest, err = http.NewRequest(method, url.String(), nil) + } + if err != nil { + return nil, err + } + + // add header parameters, if any + if len(headerParams) > 0 { + headers := http.Header{} + for h, v := range headerParams { + headers[h] = []string{v} + } + localVarRequest.Header = headers + } + + // Add the user agent to the request. + localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent) + + if ctx != nil { + // add context to the request + localVarRequest = localVarRequest.WithContext(ctx) + + // Walk through any authentication. + + } + + for header, value := range c.cfg.DefaultHeader { + localVarRequest.Header.Add(header, value) + } + return localVarRequest, nil +} + +func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) { + if len(b) == 0 { + return nil + } + if s, ok := v.(*string); ok { + *s = string(b) + return nil + } + if f, ok := v.(*os.File); ok { + f, err = os.CreateTemp("", "HttpClientFile") + if err != nil { + return + } + _, err = f.Write(b) + if err != nil { + return + } + _, err = f.Seek(0, io.SeekStart) + return + } + if f, ok := v.(**os.File); ok { + *f, err = os.CreateTemp("", "HttpClientFile") + if err != nil { + return + } + _, err = (*f).Write(b) + if err != nil { + return + } + _, err = (*f).Seek(0, io.SeekStart) + return + } + if XmlCheck.MatchString(contentType) { + if err = xml.Unmarshal(b, v); err != nil { + return err + } + return nil + } + if JsonCheck.MatchString(contentType) { + if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas + if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined + if err = unmarshalObj.UnmarshalJSON(b); err != nil { + return err + } + } else { + return errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined") + } + } else if err = json.Unmarshal(b, v); err != nil { // simple model + return err + } + return nil + } + return errors.New("undefined response type") +} + +// Add a file to the multipart request +func addFile(w *multipart.Writer, fieldName, path string) error { + file, err := os.Open(filepath.Clean(path)) + if err != nil { + return err + } + err = file.Close() + if err != nil { + return err + } + + part, err := w.CreateFormFile(fieldName, filepath.Base(path)) + if err != nil { + return err + } + _, err = io.Copy(part, file) + + return err +} + +// Set request body from an interface{} +func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { + if bodyBuf == nil { + bodyBuf = &bytes.Buffer{} + } + + if reader, ok := body.(io.Reader); ok { + _, err = bodyBuf.ReadFrom(reader) + } else if fp, ok := body.(*os.File); ok { + _, err = bodyBuf.ReadFrom(fp) + } else if b, ok := body.([]byte); ok { + _, err = bodyBuf.Write(b) + } else if s, ok := body.(string); ok { + _, err = bodyBuf.WriteString(s) + } else if s, ok := body.(*string); ok { + _, err = bodyBuf.WriteString(*s) + } else if JsonCheck.MatchString(contentType) { + err = json.NewEncoder(bodyBuf).Encode(body) + } else if XmlCheck.MatchString(contentType) { + var bs []byte + bs, err = xml.Marshal(body) + if err == nil { + bodyBuf.Write(bs) + } + } + + if err != nil { + return nil, err + } + + if bodyBuf.Len() == 0 { + err = fmt.Errorf("invalid body type %s\n", contentType) + return nil, err + } + return bodyBuf, nil +} + +// detectContentType method is used to figure out `Request.Body` content type for request header +func detectContentType(body interface{}) string { + contentType := "text/plain; charset=utf-8" + kind := reflect.TypeOf(body).Kind() + + switch kind { + case reflect.Struct, reflect.Map, reflect.Ptr: + contentType = "application/json; charset=utf-8" + case reflect.String: + contentType = "text/plain; charset=utf-8" + default: + if b, ok := body.([]byte); ok { + contentType = http.DetectContentType(b) + } else if kind == reflect.Slice { + contentType = "application/json; charset=utf-8" + } + } + + return contentType +} + +// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go +type cacheControl map[string]string + +func parseCacheControl(headers http.Header) cacheControl { + cc := cacheControl{} + ccHeader := headers.Get("Cache-Control") + for _, part := range strings.Split(ccHeader, ",") { + part = strings.Trim(part, " ") + if part == "" { + continue + } + if strings.ContainsRune(part, '=') { + keyval := strings.Split(part, "=") + cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",") + } else { + cc[part] = "" + } + } + return cc +} + +// CacheExpires helper function to determine remaining time before repeating a request. +func CacheExpires(r *http.Response) time.Time { + // Figure out when the cache expires. + var expires time.Time + now, err := time.Parse(time.RFC1123, r.Header.Get("date")) + if err != nil { + return time.Now() + } + respCacheControl := parseCacheControl(r.Header) + + if maxAge, ok := respCacheControl["max-age"]; ok { + lifetime, err := time.ParseDuration(maxAge + "s") + if err != nil { + expires = now + } else { + expires = now.Add(lifetime) + } + } else { + expiresHeader := r.Header.Get("Expires") + if expiresHeader != "" { + expires, err = time.Parse(time.RFC1123, expiresHeader) + if err != nil { + expires = now + } + } + } + return expires +} + +func strlen(s string) int { + return utf8.RuneCountInString(s) +} + +// GenericOpenAPIError Provides access to the body, error and model on returned errors. +type GenericOpenAPIError struct { + body []byte + error string + model interface{} +} + +// Error returns non-empty string if there was an error. +func (e GenericOpenAPIError) Error() string { + return e.error +} + +// Body returns the raw bytes of the response +func (e GenericOpenAPIError) Body() []byte { + return e.body +} + +// Model returns the unpacked model of the error +func (e GenericOpenAPIError) Model() interface{} { + return e.model +} + +// format error message using title and detail when model implements rfc7807 +func formatErrorMessage(status string, v interface{}) string { + str := "" + metaValue := reflect.ValueOf(v).Elem() + + if metaValue.Kind() == reflect.Struct { + field := metaValue.FieldByName("Title") + if field != (reflect.Value{}) { + str = fmt.Sprintf("%s", field.Interface()) + } + + field = metaValue.FieldByName("Detail") + if field != (reflect.Value{}) { + str = fmt.Sprintf("%s (%s)", str, field.Interface()) + } + } + + return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) +} diff --git a/sdk/go/configuration.go b/sdk/go/configuration.go new file mode 100644 index 0000000..2a6776d --- /dev/null +++ b/sdk/go/configuration.go @@ -0,0 +1,221 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "context" + "fmt" + "net/http" + "strings" +) + +// contextKeys are used to identify the type of value in the context. +// Since these are string, it is possible to get a short description of the +// context key for logging and debugging using key.String(). + +type contextKey string + +func (c contextKey) String() string { + return "auth " + string(c) +} + +var ( + // ContextAPIKeys takes a string apikey as authentication for the request + ContextAPIKeys = contextKey("apiKeys") + + // ContextServerIndex uses a server configuration from the index. + ContextServerIndex = contextKey("serverIndex") + + // ContextOperationServerIndices uses a server configuration from the index mapping. + ContextOperationServerIndices = contextKey("serverOperationIndices") + + // ContextServerVariables overrides a server configuration variables. + ContextServerVariables = contextKey("serverVariables") + + // ContextOperationServerVariables overrides a server configuration variables using operation specific values. + ContextOperationServerVariables = contextKey("serverOperationVariables") +) + +// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth +type BasicAuth struct { + UserName string `json:"userName,omitempty"` + Password string `json:"password,omitempty"` +} + +// APIKey provides API key based authentication to a request passed via context using ContextAPIKey +type APIKey struct { + Key string + Prefix string +} + +// ServerVariable stores the information about a server variable +type ServerVariable struct { + Description string + DefaultValue string + EnumValues []string +} + +// ServerConfiguration stores the information about a server +type ServerConfiguration struct { + URL string + Description string + Variables map[string]ServerVariable +} + +// ServerConfigurations stores multiple ServerConfiguration items +type ServerConfigurations []ServerConfiguration + +// Configuration stores the configuration of the API client +type Configuration struct { + Host string `json:"host,omitempty"` + Scheme string `json:"scheme,omitempty"` + DefaultHeader map[string]string `json:"defaultHeader,omitempty"` + UserAgent string `json:"userAgent,omitempty"` + Debug bool `json:"debug,omitempty"` + Servers ServerConfigurations + OperationServers map[string]ServerConfigurations + HTTPClient *http.Client +} + +// NewConfiguration returns a new Configuration object +func NewConfiguration() *Configuration { + cfg := &Configuration{ + DefaultHeader: make(map[string]string), + UserAgent: "OpenAPI-Generator/1.0.0/go", + Debug: false, + Servers: ServerConfigurations{ + { + URL: "http://localhost:8080/api/v1", + Description: "No description provided", + }, + { + URL: "https://localhost:8080/api/v1", + Description: "No description provided", + }, + }, + OperationServers: map[string]ServerConfigurations{}, + } + return cfg +} + +// AddDefaultHeader adds a new HTTP header to the default header in the request +func (c *Configuration) AddDefaultHeader(key string, value string) { + c.DefaultHeader[key] = value +} + +// URL formats template on a index using given variables +func (sc ServerConfigurations) URL(index int, variables map[string]string) (string, error) { + if index < 0 || len(sc) <= index { + return "", fmt.Errorf("index %v out of range %v", index, len(sc)-1) + } + server := sc[index] + url := server.URL + + // go through variables and replace placeholders + for name, variable := range server.Variables { + if value, ok := variables[name]; ok { + found := bool(len(variable.EnumValues) == 0) + for _, enumValue := range variable.EnumValues { + if value == enumValue { + found = true + } + } + if !found { + return "", fmt.Errorf("the variable %s in the server URL has invalid value %v. Must be %v", name, value, variable.EnumValues) + } + url = strings.Replace(url, "{"+name+"}", value, -1) + } else { + url = strings.Replace(url, "{"+name+"}", variable.DefaultValue, -1) + } + } + return url, nil +} + +// ServerURL returns URL based on server settings +func (c *Configuration) ServerURL(index int, variables map[string]string) (string, error) { + return c.Servers.URL(index, variables) +} + +func getServerIndex(ctx context.Context) (int, error) { + si := ctx.Value(ContextServerIndex) + if si != nil { + if index, ok := si.(int); ok { + return index, nil + } + return 0, reportError("Invalid type %T should be int", si) + } + return 0, nil +} + +func getServerOperationIndex(ctx context.Context, endpoint string) (int, error) { + osi := ctx.Value(ContextOperationServerIndices) + if osi != nil { + if operationIndices, ok := osi.(map[string]int); !ok { + return 0, reportError("Invalid type %T should be map[string]int", osi) + } else { + index, ok := operationIndices[endpoint] + if ok { + return index, nil + } + } + } + return getServerIndex(ctx) +} + +func getServerVariables(ctx context.Context) (map[string]string, error) { + sv := ctx.Value(ContextServerVariables) + if sv != nil { + if variables, ok := sv.(map[string]string); ok { + return variables, nil + } + return nil, reportError("ctx value of ContextServerVariables has invalid type %T should be map[string]string", sv) + } + return nil, nil +} + +func getServerOperationVariables(ctx context.Context, endpoint string) (map[string]string, error) { + osv := ctx.Value(ContextOperationServerVariables) + if osv != nil { + if operationVariables, ok := osv.(map[string]map[string]string); !ok { + return nil, reportError("ctx value of ContextOperationServerVariables has invalid type %T should be map[string]map[string]string", osv) + } else { + variables, ok := operationVariables[endpoint] + if ok { + return variables, nil + } + } + } + return getServerVariables(ctx) +} + +// ServerURLWithContext returns a new server URL given an endpoint +func (c *Configuration) ServerURLWithContext(ctx context.Context, endpoint string) (string, error) { + sc, ok := c.OperationServers[endpoint] + if !ok { + sc = c.Servers + } + + if ctx == nil { + return sc.URL(0, nil) + } + + index, err := getServerOperationIndex(ctx, endpoint) + if err != nil { + return "", err + } + + variables, err := getServerOperationVariables(ctx, endpoint) + if err != nil { + return "", err + } + + return sc.URL(index, variables) +} diff --git a/sdk/go/docs/AuthAPI.md b/sdk/go/docs/AuthAPI.md new file mode 100644 index 0000000..b3b905a --- /dev/null +++ b/sdk/go/docs/AuthAPI.md @@ -0,0 +1,338 @@ +# \AuthAPI + +All URIs are relative to *http://localhost:8080/api/v1* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**AuthCallback**](AuthAPI.md#AuthCallback) | **Get** /auth/{provider}/callback | Handle social login callback +[**AuthStart**](AuthAPI.md#AuthStart) | **Post** /auth/{provider}/start | Begin social login +[**GetJWKS**](AuthAPI.md#GetJWKS) | **Get** /.well-known/jwks.json | Get JWKS +[**Logout**](AuthAPI.md#Logout) | **Post** /auth/logout | Revoke refresh token family (logout everywhere) +[**Refresh**](AuthAPI.md#Refresh) | **Post** /auth/refresh | Rotate refresh token + + + +## AuthCallback + +> DtoTokenPair AuthCallback(ctx, provider).Execute() + +Handle social login callback + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + provider := "provider_example" // string | google|github + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.AuthAPI.AuthCallback(context.Background(), provider).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `AuthAPI.AuthCallback``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `AuthCallback`: DtoTokenPair + fmt.Fprintf(os.Stdout, "Response from `AuthAPI.AuthCallback`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**provider** | **string** | google|github | + +### Other Parameters + +Other parameters are passed through a pointer to a apiAuthCallbackRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + +[**DtoTokenPair**](DtoTokenPair.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## AuthStart + +> DtoAuthStartResponse AuthStart(ctx, provider).Execute() + +Begin social login + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + provider := "provider_example" // string | google|github + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.AuthAPI.AuthStart(context.Background(), provider).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `AuthAPI.AuthStart``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `AuthStart`: DtoAuthStartResponse + fmt.Fprintf(os.Stdout, "Response from `AuthAPI.AuthStart`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**provider** | **string** | google|github | + +### Other Parameters + +Other parameters are passed through a pointer to a apiAuthStartRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + +[**DtoAuthStartResponse**](DtoAuthStartResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## GetJWKS + +> DtoJWKS GetJWKS(ctx).Execute() + +Get JWKS + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.AuthAPI.GetJWKS(context.Background()).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `AuthAPI.GetJWKS``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetJWKS`: DtoJWKS + fmt.Fprintf(os.Stdout, "Response from `AuthAPI.GetJWKS`: %v\n", resp) +} +``` + +### Path Parameters + +This endpoint does not need any parameter. + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetJWKSRequest struct via the builder pattern + + +### Return type + +[**DtoJWKS**](DtoJWKS.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## Logout + +> Logout(ctx).Body(body).Execute() + +Revoke refresh token family (logout everywhere) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + body := *openapiclient.NewDtoLogoutRequest() // DtoLogoutRequest | Refresh token + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.AuthAPI.Logout(context.Background()).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `AuthAPI.Logout``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiLogoutRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**DtoLogoutRequest**](DtoLogoutRequest.md) | Refresh token | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## Refresh + +> DtoTokenPair Refresh(ctx).Body(body).Execute() + +Rotate refresh token + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + body := *openapiclient.NewDtoRefreshRequest() // DtoRefreshRequest | Refresh token + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.AuthAPI.Refresh(context.Background()).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `AuthAPI.Refresh``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `Refresh`: DtoTokenPair + fmt.Fprintf(os.Stdout, "Response from `AuthAPI.Refresh`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiRefreshRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**DtoRefreshRequest**](DtoRefreshRequest.md) | Refresh token | + +### Return type + +[**DtoTokenPair**](DtoTokenPair.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/sdk/go/docs/DtoAuthStartResponse.md b/sdk/go/docs/DtoAuthStartResponse.md new file mode 100644 index 0000000..4a47ef6 --- /dev/null +++ b/sdk/go/docs/DtoAuthStartResponse.md @@ -0,0 +1,56 @@ +# DtoAuthStartResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AuthUrl** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoAuthStartResponse + +`func NewDtoAuthStartResponse() *DtoAuthStartResponse` + +NewDtoAuthStartResponse instantiates a new DtoAuthStartResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoAuthStartResponseWithDefaults + +`func NewDtoAuthStartResponseWithDefaults() *DtoAuthStartResponse` + +NewDtoAuthStartResponseWithDefaults instantiates a new DtoAuthStartResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetAuthUrl + +`func (o *DtoAuthStartResponse) GetAuthUrl() string` + +GetAuthUrl returns the AuthUrl field if non-nil, zero value otherwise. + +### GetAuthUrlOk + +`func (o *DtoAuthStartResponse) GetAuthUrlOk() (*string, bool)` + +GetAuthUrlOk returns a tuple with the AuthUrl field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAuthUrl + +`func (o *DtoAuthStartResponse) SetAuthUrl(v string)` + +SetAuthUrl sets AuthUrl field to given value. + +### HasAuthUrl + +`func (o *DtoAuthStartResponse) HasAuthUrl() bool` + +HasAuthUrl returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoCreateSSHRequest.md b/sdk/go/docs/DtoCreateSSHRequest.md new file mode 100644 index 0000000..03a4894 --- /dev/null +++ b/sdk/go/docs/DtoCreateSSHRequest.md @@ -0,0 +1,134 @@ +# DtoCreateSSHRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Bits** | Pointer to **int32** | Only for RSA | [optional] +**Comment** | Pointer to **string** | | [optional] +**Name** | Pointer to **string** | | [optional] +**Type** | Pointer to **string** | \"rsa\" (default) or \"ed25519\" | [optional] + +## Methods + +### NewDtoCreateSSHRequest + +`func NewDtoCreateSSHRequest() *DtoCreateSSHRequest` + +NewDtoCreateSSHRequest instantiates a new DtoCreateSSHRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoCreateSSHRequestWithDefaults + +`func NewDtoCreateSSHRequestWithDefaults() *DtoCreateSSHRequest` + +NewDtoCreateSSHRequestWithDefaults instantiates a new DtoCreateSSHRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetBits + +`func (o *DtoCreateSSHRequest) GetBits() int32` + +GetBits returns the Bits field if non-nil, zero value otherwise. + +### GetBitsOk + +`func (o *DtoCreateSSHRequest) GetBitsOk() (*int32, bool)` + +GetBitsOk returns a tuple with the Bits field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetBits + +`func (o *DtoCreateSSHRequest) SetBits(v int32)` + +SetBits sets Bits field to given value. + +### HasBits + +`func (o *DtoCreateSSHRequest) HasBits() bool` + +HasBits returns a boolean if a field has been set. + +### GetComment + +`func (o *DtoCreateSSHRequest) GetComment() string` + +GetComment returns the Comment field if non-nil, zero value otherwise. + +### GetCommentOk + +`func (o *DtoCreateSSHRequest) GetCommentOk() (*string, bool)` + +GetCommentOk returns a tuple with the Comment field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetComment + +`func (o *DtoCreateSSHRequest) SetComment(v string)` + +SetComment sets Comment field to given value. + +### HasComment + +`func (o *DtoCreateSSHRequest) HasComment() bool` + +HasComment returns a boolean if a field has been set. + +### GetName + +`func (o *DtoCreateSSHRequest) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *DtoCreateSSHRequest) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *DtoCreateSSHRequest) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *DtoCreateSSHRequest) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetType + +`func (o *DtoCreateSSHRequest) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *DtoCreateSSHRequest) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *DtoCreateSSHRequest) SetType(v string)` + +SetType sets Type field to given value. + +### HasType + +`func (o *DtoCreateSSHRequest) HasType() bool` + +HasType returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoCreateServerRequest.md b/sdk/go/docs/DtoCreateServerRequest.md new file mode 100644 index 0000000..05acfb2 --- /dev/null +++ b/sdk/go/docs/DtoCreateServerRequest.md @@ -0,0 +1,212 @@ +# DtoCreateServerRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Hostname** | Pointer to **string** | | [optional] +**PrivateIpAddress** | Pointer to **string** | | [optional] +**PublicIpAddress** | Pointer to **string** | | [optional] +**Role** | Pointer to **string** | | [optional] +**SshKeyId** | Pointer to **string** | | [optional] +**SshUser** | Pointer to **string** | | [optional] +**Status** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoCreateServerRequest + +`func NewDtoCreateServerRequest() *DtoCreateServerRequest` + +NewDtoCreateServerRequest instantiates a new DtoCreateServerRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoCreateServerRequestWithDefaults + +`func NewDtoCreateServerRequestWithDefaults() *DtoCreateServerRequest` + +NewDtoCreateServerRequestWithDefaults instantiates a new DtoCreateServerRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetHostname + +`func (o *DtoCreateServerRequest) GetHostname() string` + +GetHostname returns the Hostname field if non-nil, zero value otherwise. + +### GetHostnameOk + +`func (o *DtoCreateServerRequest) GetHostnameOk() (*string, bool)` + +GetHostnameOk returns a tuple with the Hostname field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetHostname + +`func (o *DtoCreateServerRequest) SetHostname(v string)` + +SetHostname sets Hostname field to given value. + +### HasHostname + +`func (o *DtoCreateServerRequest) HasHostname() bool` + +HasHostname returns a boolean if a field has been set. + +### GetPrivateIpAddress + +`func (o *DtoCreateServerRequest) GetPrivateIpAddress() string` + +GetPrivateIpAddress returns the PrivateIpAddress field if non-nil, zero value otherwise. + +### GetPrivateIpAddressOk + +`func (o *DtoCreateServerRequest) GetPrivateIpAddressOk() (*string, bool)` + +GetPrivateIpAddressOk returns a tuple with the PrivateIpAddress field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPrivateIpAddress + +`func (o *DtoCreateServerRequest) SetPrivateIpAddress(v string)` + +SetPrivateIpAddress sets PrivateIpAddress field to given value. + +### HasPrivateIpAddress + +`func (o *DtoCreateServerRequest) HasPrivateIpAddress() bool` + +HasPrivateIpAddress returns a boolean if a field has been set. + +### GetPublicIpAddress + +`func (o *DtoCreateServerRequest) GetPublicIpAddress() string` + +GetPublicIpAddress returns the PublicIpAddress field if non-nil, zero value otherwise. + +### GetPublicIpAddressOk + +`func (o *DtoCreateServerRequest) GetPublicIpAddressOk() (*string, bool)` + +GetPublicIpAddressOk returns a tuple with the PublicIpAddress field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPublicIpAddress + +`func (o *DtoCreateServerRequest) SetPublicIpAddress(v string)` + +SetPublicIpAddress sets PublicIpAddress field to given value. + +### HasPublicIpAddress + +`func (o *DtoCreateServerRequest) HasPublicIpAddress() bool` + +HasPublicIpAddress returns a boolean if a field has been set. + +### GetRole + +`func (o *DtoCreateServerRequest) GetRole() string` + +GetRole returns the Role field if non-nil, zero value otherwise. + +### GetRoleOk + +`func (o *DtoCreateServerRequest) GetRoleOk() (*string, bool)` + +GetRoleOk returns a tuple with the Role field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRole + +`func (o *DtoCreateServerRequest) SetRole(v string)` + +SetRole sets Role field to given value. + +### HasRole + +`func (o *DtoCreateServerRequest) HasRole() bool` + +HasRole returns a boolean if a field has been set. + +### GetSshKeyId + +`func (o *DtoCreateServerRequest) GetSshKeyId() string` + +GetSshKeyId returns the SshKeyId field if non-nil, zero value otherwise. + +### GetSshKeyIdOk + +`func (o *DtoCreateServerRequest) GetSshKeyIdOk() (*string, bool)` + +GetSshKeyIdOk returns a tuple with the SshKeyId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSshKeyId + +`func (o *DtoCreateServerRequest) SetSshKeyId(v string)` + +SetSshKeyId sets SshKeyId field to given value. + +### HasSshKeyId + +`func (o *DtoCreateServerRequest) HasSshKeyId() bool` + +HasSshKeyId returns a boolean if a field has been set. + +### GetSshUser + +`func (o *DtoCreateServerRequest) GetSshUser() string` + +GetSshUser returns the SshUser field if non-nil, zero value otherwise. + +### GetSshUserOk + +`func (o *DtoCreateServerRequest) GetSshUserOk() (*string, bool)` + +GetSshUserOk returns a tuple with the SshUser field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSshUser + +`func (o *DtoCreateServerRequest) SetSshUser(v string)` + +SetSshUser sets SshUser field to given value. + +### HasSshUser + +`func (o *DtoCreateServerRequest) HasSshUser() bool` + +HasSshUser returns a boolean if a field has been set. + +### GetStatus + +`func (o *DtoCreateServerRequest) GetStatus() string` + +GetStatus returns the Status field if non-nil, zero value otherwise. + +### GetStatusOk + +`func (o *DtoCreateServerRequest) GetStatusOk() (*string, bool)` + +GetStatusOk returns a tuple with the Status field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetStatus + +`func (o *DtoCreateServerRequest) SetStatus(v string)` + +SetStatus sets Status field to given value. + +### HasStatus + +`func (o *DtoCreateServerRequest) HasStatus() bool` + +HasStatus returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoCreateTaintRequest.md b/sdk/go/docs/DtoCreateTaintRequest.md new file mode 100644 index 0000000..78367b4 --- /dev/null +++ b/sdk/go/docs/DtoCreateTaintRequest.md @@ -0,0 +1,108 @@ +# DtoCreateTaintRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Effect** | Pointer to **string** | | [optional] +**Key** | Pointer to **string** | | [optional] +**Value** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoCreateTaintRequest + +`func NewDtoCreateTaintRequest() *DtoCreateTaintRequest` + +NewDtoCreateTaintRequest instantiates a new DtoCreateTaintRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoCreateTaintRequestWithDefaults + +`func NewDtoCreateTaintRequestWithDefaults() *DtoCreateTaintRequest` + +NewDtoCreateTaintRequestWithDefaults instantiates a new DtoCreateTaintRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetEffect + +`func (o *DtoCreateTaintRequest) GetEffect() string` + +GetEffect returns the Effect field if non-nil, zero value otherwise. + +### GetEffectOk + +`func (o *DtoCreateTaintRequest) GetEffectOk() (*string, bool)` + +GetEffectOk returns a tuple with the Effect field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEffect + +`func (o *DtoCreateTaintRequest) SetEffect(v string)` + +SetEffect sets Effect field to given value. + +### HasEffect + +`func (o *DtoCreateTaintRequest) HasEffect() bool` + +HasEffect returns a boolean if a field has been set. + +### GetKey + +`func (o *DtoCreateTaintRequest) GetKey() string` + +GetKey returns the Key field if non-nil, zero value otherwise. + +### GetKeyOk + +`func (o *DtoCreateTaintRequest) GetKeyOk() (*string, bool)` + +GetKeyOk returns a tuple with the Key field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKey + +`func (o *DtoCreateTaintRequest) SetKey(v string)` + +SetKey sets Key field to given value. + +### HasKey + +`func (o *DtoCreateTaintRequest) HasKey() bool` + +HasKey returns a boolean if a field has been set. + +### GetValue + +`func (o *DtoCreateTaintRequest) GetValue() string` + +GetValue returns the Value field if non-nil, zero value otherwise. + +### GetValueOk + +`func (o *DtoCreateTaintRequest) GetValueOk() (*string, bool)` + +GetValueOk returns a tuple with the Value field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetValue + +`func (o *DtoCreateTaintRequest) SetValue(v string)` + +SetValue sets Value field to given value. + +### HasValue + +`func (o *DtoCreateTaintRequest) HasValue() bool` + +HasValue returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoJWK.md b/sdk/go/docs/DtoJWK.md new file mode 100644 index 0000000..bbfca3e --- /dev/null +++ b/sdk/go/docs/DtoJWK.md @@ -0,0 +1,212 @@ +# DtoJWK + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Alg** | Pointer to **string** | | [optional] +**E** | Pointer to **string** | | [optional] +**Kid** | Pointer to **string** | | [optional] +**Kty** | Pointer to **string** | | [optional] +**N** | Pointer to **string** | | [optional] +**Use** | Pointer to **string** | | [optional] +**X** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoJWK + +`func NewDtoJWK() *DtoJWK` + +NewDtoJWK instantiates a new DtoJWK object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoJWKWithDefaults + +`func NewDtoJWKWithDefaults() *DtoJWK` + +NewDtoJWKWithDefaults instantiates a new DtoJWK object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetAlg + +`func (o *DtoJWK) GetAlg() string` + +GetAlg returns the Alg field if non-nil, zero value otherwise. + +### GetAlgOk + +`func (o *DtoJWK) GetAlgOk() (*string, bool)` + +GetAlgOk returns a tuple with the Alg field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAlg + +`func (o *DtoJWK) SetAlg(v string)` + +SetAlg sets Alg field to given value. + +### HasAlg + +`func (o *DtoJWK) HasAlg() bool` + +HasAlg returns a boolean if a field has been set. + +### GetE + +`func (o *DtoJWK) GetE() string` + +GetE returns the E field if non-nil, zero value otherwise. + +### GetEOk + +`func (o *DtoJWK) GetEOk() (*string, bool)` + +GetEOk returns a tuple with the E field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetE + +`func (o *DtoJWK) SetE(v string)` + +SetE sets E field to given value. + +### HasE + +`func (o *DtoJWK) HasE() bool` + +HasE returns a boolean if a field has been set. + +### GetKid + +`func (o *DtoJWK) GetKid() string` + +GetKid returns the Kid field if non-nil, zero value otherwise. + +### GetKidOk + +`func (o *DtoJWK) GetKidOk() (*string, bool)` + +GetKidOk returns a tuple with the Kid field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKid + +`func (o *DtoJWK) SetKid(v string)` + +SetKid sets Kid field to given value. + +### HasKid + +`func (o *DtoJWK) HasKid() bool` + +HasKid returns a boolean if a field has been set. + +### GetKty + +`func (o *DtoJWK) GetKty() string` + +GetKty returns the Kty field if non-nil, zero value otherwise. + +### GetKtyOk + +`func (o *DtoJWK) GetKtyOk() (*string, bool)` + +GetKtyOk returns a tuple with the Kty field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKty + +`func (o *DtoJWK) SetKty(v string)` + +SetKty sets Kty field to given value. + +### HasKty + +`func (o *DtoJWK) HasKty() bool` + +HasKty returns a boolean if a field has been set. + +### GetN + +`func (o *DtoJWK) GetN() string` + +GetN returns the N field if non-nil, zero value otherwise. + +### GetNOk + +`func (o *DtoJWK) GetNOk() (*string, bool)` + +GetNOk returns a tuple with the N field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetN + +`func (o *DtoJWK) SetN(v string)` + +SetN sets N field to given value. + +### HasN + +`func (o *DtoJWK) HasN() bool` + +HasN returns a boolean if a field has been set. + +### GetUse + +`func (o *DtoJWK) GetUse() string` + +GetUse returns the Use field if non-nil, zero value otherwise. + +### GetUseOk + +`func (o *DtoJWK) GetUseOk() (*string, bool)` + +GetUseOk returns a tuple with the Use field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUse + +`func (o *DtoJWK) SetUse(v string)` + +SetUse sets Use field to given value. + +### HasUse + +`func (o *DtoJWK) HasUse() bool` + +HasUse returns a boolean if a field has been set. + +### GetX + +`func (o *DtoJWK) GetX() string` + +GetX returns the X field if non-nil, zero value otherwise. + +### GetXOk + +`func (o *DtoJWK) GetXOk() (*string, bool)` + +GetXOk returns a tuple with the X field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetX + +`func (o *DtoJWK) SetX(v string)` + +SetX sets X field to given value. + +### HasX + +`func (o *DtoJWK) HasX() bool` + +HasX returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoJWKS.md b/sdk/go/docs/DtoJWKS.md new file mode 100644 index 0000000..9efce4d --- /dev/null +++ b/sdk/go/docs/DtoJWKS.md @@ -0,0 +1,56 @@ +# DtoJWKS + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Keys** | Pointer to [**[]DtoJWK**](DtoJWK.md) | | [optional] + +## Methods + +### NewDtoJWKS + +`func NewDtoJWKS() *DtoJWKS` + +NewDtoJWKS instantiates a new DtoJWKS object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoJWKSWithDefaults + +`func NewDtoJWKSWithDefaults() *DtoJWKS` + +NewDtoJWKSWithDefaults instantiates a new DtoJWKS object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetKeys + +`func (o *DtoJWKS) GetKeys() []DtoJWK` + +GetKeys returns the Keys field if non-nil, zero value otherwise. + +### GetKeysOk + +`func (o *DtoJWKS) GetKeysOk() (*[]DtoJWK, bool)` + +GetKeysOk returns a tuple with the Keys field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKeys + +`func (o *DtoJWKS) SetKeys(v []DtoJWK)` + +SetKeys sets Keys field to given value. + +### HasKeys + +`func (o *DtoJWKS) HasKeys() bool` + +HasKeys returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoLogoutRequest.md b/sdk/go/docs/DtoLogoutRequest.md new file mode 100644 index 0000000..05af9bd --- /dev/null +++ b/sdk/go/docs/DtoLogoutRequest.md @@ -0,0 +1,56 @@ +# DtoLogoutRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**RefreshToken** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoLogoutRequest + +`func NewDtoLogoutRequest() *DtoLogoutRequest` + +NewDtoLogoutRequest instantiates a new DtoLogoutRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoLogoutRequestWithDefaults + +`func NewDtoLogoutRequestWithDefaults() *DtoLogoutRequest` + +NewDtoLogoutRequestWithDefaults instantiates a new DtoLogoutRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetRefreshToken + +`func (o *DtoLogoutRequest) GetRefreshToken() string` + +GetRefreshToken returns the RefreshToken field if non-nil, zero value otherwise. + +### GetRefreshTokenOk + +`func (o *DtoLogoutRequest) GetRefreshTokenOk() (*string, bool)` + +GetRefreshTokenOk returns a tuple with the RefreshToken field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRefreshToken + +`func (o *DtoLogoutRequest) SetRefreshToken(v string)` + +SetRefreshToken sets RefreshToken field to given value. + +### HasRefreshToken + +`func (o *DtoLogoutRequest) HasRefreshToken() bool` + +HasRefreshToken returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoRefreshRequest.md b/sdk/go/docs/DtoRefreshRequest.md new file mode 100644 index 0000000..2c95a50 --- /dev/null +++ b/sdk/go/docs/DtoRefreshRequest.md @@ -0,0 +1,56 @@ +# DtoRefreshRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**RefreshToken** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoRefreshRequest + +`func NewDtoRefreshRequest() *DtoRefreshRequest` + +NewDtoRefreshRequest instantiates a new DtoRefreshRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoRefreshRequestWithDefaults + +`func NewDtoRefreshRequestWithDefaults() *DtoRefreshRequest` + +NewDtoRefreshRequestWithDefaults instantiates a new DtoRefreshRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetRefreshToken + +`func (o *DtoRefreshRequest) GetRefreshToken() string` + +GetRefreshToken returns the RefreshToken field if non-nil, zero value otherwise. + +### GetRefreshTokenOk + +`func (o *DtoRefreshRequest) GetRefreshTokenOk() (*string, bool)` + +GetRefreshTokenOk returns a tuple with the RefreshToken field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRefreshToken + +`func (o *DtoRefreshRequest) SetRefreshToken(v string)` + +SetRefreshToken sets RefreshToken field to given value. + +### HasRefreshToken + +`func (o *DtoRefreshRequest) HasRefreshToken() bool` + +HasRefreshToken returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoServerResponse.md b/sdk/go/docs/DtoServerResponse.md new file mode 100644 index 0000000..259bd8f --- /dev/null +++ b/sdk/go/docs/DtoServerResponse.md @@ -0,0 +1,316 @@ +# DtoServerResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CreatedAt** | Pointer to **string** | | [optional] +**Hostname** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | | [optional] +**OrganizationId** | Pointer to **string** | | [optional] +**PrivateIpAddress** | Pointer to **string** | | [optional] +**PublicIpAddress** | Pointer to **string** | | [optional] +**Role** | Pointer to **string** | | [optional] +**SshKeyId** | Pointer to **string** | | [optional] +**SshUser** | Pointer to **string** | | [optional] +**Status** | Pointer to **string** | | [optional] +**UpdatedAt** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoServerResponse + +`func NewDtoServerResponse() *DtoServerResponse` + +NewDtoServerResponse instantiates a new DtoServerResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoServerResponseWithDefaults + +`func NewDtoServerResponseWithDefaults() *DtoServerResponse` + +NewDtoServerResponseWithDefaults instantiates a new DtoServerResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCreatedAt + +`func (o *DtoServerResponse) GetCreatedAt() string` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *DtoServerResponse) GetCreatedAtOk() (*string, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *DtoServerResponse) SetCreatedAt(v string)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *DtoServerResponse) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetHostname + +`func (o *DtoServerResponse) GetHostname() string` + +GetHostname returns the Hostname field if non-nil, zero value otherwise. + +### GetHostnameOk + +`func (o *DtoServerResponse) GetHostnameOk() (*string, bool)` + +GetHostnameOk returns a tuple with the Hostname field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetHostname + +`func (o *DtoServerResponse) SetHostname(v string)` + +SetHostname sets Hostname field to given value. + +### HasHostname + +`func (o *DtoServerResponse) HasHostname() bool` + +HasHostname returns a boolean if a field has been set. + +### GetId + +`func (o *DtoServerResponse) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *DtoServerResponse) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *DtoServerResponse) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *DtoServerResponse) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetOrganizationId + +`func (o *DtoServerResponse) GetOrganizationId() string` + +GetOrganizationId returns the OrganizationId field if non-nil, zero value otherwise. + +### GetOrganizationIdOk + +`func (o *DtoServerResponse) GetOrganizationIdOk() (*string, bool)` + +GetOrganizationIdOk returns a tuple with the OrganizationId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOrganizationId + +`func (o *DtoServerResponse) SetOrganizationId(v string)` + +SetOrganizationId sets OrganizationId field to given value. + +### HasOrganizationId + +`func (o *DtoServerResponse) HasOrganizationId() bool` + +HasOrganizationId returns a boolean if a field has been set. + +### GetPrivateIpAddress + +`func (o *DtoServerResponse) GetPrivateIpAddress() string` + +GetPrivateIpAddress returns the PrivateIpAddress field if non-nil, zero value otherwise. + +### GetPrivateIpAddressOk + +`func (o *DtoServerResponse) GetPrivateIpAddressOk() (*string, bool)` + +GetPrivateIpAddressOk returns a tuple with the PrivateIpAddress field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPrivateIpAddress + +`func (o *DtoServerResponse) SetPrivateIpAddress(v string)` + +SetPrivateIpAddress sets PrivateIpAddress field to given value. + +### HasPrivateIpAddress + +`func (o *DtoServerResponse) HasPrivateIpAddress() bool` + +HasPrivateIpAddress returns a boolean if a field has been set. + +### GetPublicIpAddress + +`func (o *DtoServerResponse) GetPublicIpAddress() string` + +GetPublicIpAddress returns the PublicIpAddress field if non-nil, zero value otherwise. + +### GetPublicIpAddressOk + +`func (o *DtoServerResponse) GetPublicIpAddressOk() (*string, bool)` + +GetPublicIpAddressOk returns a tuple with the PublicIpAddress field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPublicIpAddress + +`func (o *DtoServerResponse) SetPublicIpAddress(v string)` + +SetPublicIpAddress sets PublicIpAddress field to given value. + +### HasPublicIpAddress + +`func (o *DtoServerResponse) HasPublicIpAddress() bool` + +HasPublicIpAddress returns a boolean if a field has been set. + +### GetRole + +`func (o *DtoServerResponse) GetRole() string` + +GetRole returns the Role field if non-nil, zero value otherwise. + +### GetRoleOk + +`func (o *DtoServerResponse) GetRoleOk() (*string, bool)` + +GetRoleOk returns a tuple with the Role field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRole + +`func (o *DtoServerResponse) SetRole(v string)` + +SetRole sets Role field to given value. + +### HasRole + +`func (o *DtoServerResponse) HasRole() bool` + +HasRole returns a boolean if a field has been set. + +### GetSshKeyId + +`func (o *DtoServerResponse) GetSshKeyId() string` + +GetSshKeyId returns the SshKeyId field if non-nil, zero value otherwise. + +### GetSshKeyIdOk + +`func (o *DtoServerResponse) GetSshKeyIdOk() (*string, bool)` + +GetSshKeyIdOk returns a tuple with the SshKeyId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSshKeyId + +`func (o *DtoServerResponse) SetSshKeyId(v string)` + +SetSshKeyId sets SshKeyId field to given value. + +### HasSshKeyId + +`func (o *DtoServerResponse) HasSshKeyId() bool` + +HasSshKeyId returns a boolean if a field has been set. + +### GetSshUser + +`func (o *DtoServerResponse) GetSshUser() string` + +GetSshUser returns the SshUser field if non-nil, zero value otherwise. + +### GetSshUserOk + +`func (o *DtoServerResponse) GetSshUserOk() (*string, bool)` + +GetSshUserOk returns a tuple with the SshUser field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSshUser + +`func (o *DtoServerResponse) SetSshUser(v string)` + +SetSshUser sets SshUser field to given value. + +### HasSshUser + +`func (o *DtoServerResponse) HasSshUser() bool` + +HasSshUser returns a boolean if a field has been set. + +### GetStatus + +`func (o *DtoServerResponse) GetStatus() string` + +GetStatus returns the Status field if non-nil, zero value otherwise. + +### GetStatusOk + +`func (o *DtoServerResponse) GetStatusOk() (*string, bool)` + +GetStatusOk returns a tuple with the Status field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetStatus + +`func (o *DtoServerResponse) SetStatus(v string)` + +SetStatus sets Status field to given value. + +### HasStatus + +`func (o *DtoServerResponse) HasStatus() bool` + +HasStatus returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *DtoServerResponse) GetUpdatedAt() string` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *DtoServerResponse) GetUpdatedAtOk() (*string, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *DtoServerResponse) SetUpdatedAt(v string)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *DtoServerResponse) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoSshResponse.md b/sdk/go/docs/DtoSshResponse.md new file mode 100644 index 0000000..5ae8b88 --- /dev/null +++ b/sdk/go/docs/DtoSshResponse.md @@ -0,0 +1,212 @@ +# DtoSshResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CreatedAt** | Pointer to **string** | | [optional] +**Fingerprint** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | | [optional] +**Name** | Pointer to **string** | | [optional] +**OrganizationId** | Pointer to **string** | | [optional] +**PublicKey** | Pointer to **string** | | [optional] +**UpdatedAt** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoSshResponse + +`func NewDtoSshResponse() *DtoSshResponse` + +NewDtoSshResponse instantiates a new DtoSshResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoSshResponseWithDefaults + +`func NewDtoSshResponseWithDefaults() *DtoSshResponse` + +NewDtoSshResponseWithDefaults instantiates a new DtoSshResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCreatedAt + +`func (o *DtoSshResponse) GetCreatedAt() string` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *DtoSshResponse) GetCreatedAtOk() (*string, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *DtoSshResponse) SetCreatedAt(v string)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *DtoSshResponse) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetFingerprint + +`func (o *DtoSshResponse) GetFingerprint() string` + +GetFingerprint returns the Fingerprint field if non-nil, zero value otherwise. + +### GetFingerprintOk + +`func (o *DtoSshResponse) GetFingerprintOk() (*string, bool)` + +GetFingerprintOk returns a tuple with the Fingerprint field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetFingerprint + +`func (o *DtoSshResponse) SetFingerprint(v string)` + +SetFingerprint sets Fingerprint field to given value. + +### HasFingerprint + +`func (o *DtoSshResponse) HasFingerprint() bool` + +HasFingerprint returns a boolean if a field has been set. + +### GetId + +`func (o *DtoSshResponse) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *DtoSshResponse) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *DtoSshResponse) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *DtoSshResponse) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetName + +`func (o *DtoSshResponse) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *DtoSshResponse) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *DtoSshResponse) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *DtoSshResponse) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetOrganizationId + +`func (o *DtoSshResponse) GetOrganizationId() string` + +GetOrganizationId returns the OrganizationId field if non-nil, zero value otherwise. + +### GetOrganizationIdOk + +`func (o *DtoSshResponse) GetOrganizationIdOk() (*string, bool)` + +GetOrganizationIdOk returns a tuple with the OrganizationId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOrganizationId + +`func (o *DtoSshResponse) SetOrganizationId(v string)` + +SetOrganizationId sets OrganizationId field to given value. + +### HasOrganizationId + +`func (o *DtoSshResponse) HasOrganizationId() bool` + +HasOrganizationId returns a boolean if a field has been set. + +### GetPublicKey + +`func (o *DtoSshResponse) GetPublicKey() string` + +GetPublicKey returns the PublicKey field if non-nil, zero value otherwise. + +### GetPublicKeyOk + +`func (o *DtoSshResponse) GetPublicKeyOk() (*string, bool)` + +GetPublicKeyOk returns a tuple with the PublicKey field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPublicKey + +`func (o *DtoSshResponse) SetPublicKey(v string)` + +SetPublicKey sets PublicKey field to given value. + +### HasPublicKey + +`func (o *DtoSshResponse) HasPublicKey() bool` + +HasPublicKey returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *DtoSshResponse) GetUpdatedAt() string` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *DtoSshResponse) GetUpdatedAtOk() (*string, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *DtoSshResponse) SetUpdatedAt(v string)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *DtoSshResponse) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoSshRevealResponse.md b/sdk/go/docs/DtoSshRevealResponse.md new file mode 100644 index 0000000..9a196c4 --- /dev/null +++ b/sdk/go/docs/DtoSshRevealResponse.md @@ -0,0 +1,238 @@ +# DtoSshRevealResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CreatedAt** | Pointer to **string** | | [optional] +**Fingerprint** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | | [optional] +**Name** | Pointer to **string** | | [optional] +**OrganizationId** | Pointer to **string** | | [optional] +**PrivateKey** | Pointer to **string** | | [optional] +**PublicKey** | Pointer to **string** | | [optional] +**UpdatedAt** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoSshRevealResponse + +`func NewDtoSshRevealResponse() *DtoSshRevealResponse` + +NewDtoSshRevealResponse instantiates a new DtoSshRevealResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoSshRevealResponseWithDefaults + +`func NewDtoSshRevealResponseWithDefaults() *DtoSshRevealResponse` + +NewDtoSshRevealResponseWithDefaults instantiates a new DtoSshRevealResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCreatedAt + +`func (o *DtoSshRevealResponse) GetCreatedAt() string` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *DtoSshRevealResponse) GetCreatedAtOk() (*string, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *DtoSshRevealResponse) SetCreatedAt(v string)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *DtoSshRevealResponse) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetFingerprint + +`func (o *DtoSshRevealResponse) GetFingerprint() string` + +GetFingerprint returns the Fingerprint field if non-nil, zero value otherwise. + +### GetFingerprintOk + +`func (o *DtoSshRevealResponse) GetFingerprintOk() (*string, bool)` + +GetFingerprintOk returns a tuple with the Fingerprint field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetFingerprint + +`func (o *DtoSshRevealResponse) SetFingerprint(v string)` + +SetFingerprint sets Fingerprint field to given value. + +### HasFingerprint + +`func (o *DtoSshRevealResponse) HasFingerprint() bool` + +HasFingerprint returns a boolean if a field has been set. + +### GetId + +`func (o *DtoSshRevealResponse) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *DtoSshRevealResponse) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *DtoSshRevealResponse) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *DtoSshRevealResponse) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetName + +`func (o *DtoSshRevealResponse) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *DtoSshRevealResponse) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *DtoSshRevealResponse) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *DtoSshRevealResponse) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetOrganizationId + +`func (o *DtoSshRevealResponse) GetOrganizationId() string` + +GetOrganizationId returns the OrganizationId field if non-nil, zero value otherwise. + +### GetOrganizationIdOk + +`func (o *DtoSshRevealResponse) GetOrganizationIdOk() (*string, bool)` + +GetOrganizationIdOk returns a tuple with the OrganizationId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOrganizationId + +`func (o *DtoSshRevealResponse) SetOrganizationId(v string)` + +SetOrganizationId sets OrganizationId field to given value. + +### HasOrganizationId + +`func (o *DtoSshRevealResponse) HasOrganizationId() bool` + +HasOrganizationId returns a boolean if a field has been set. + +### GetPrivateKey + +`func (o *DtoSshRevealResponse) GetPrivateKey() string` + +GetPrivateKey returns the PrivateKey field if non-nil, zero value otherwise. + +### GetPrivateKeyOk + +`func (o *DtoSshRevealResponse) GetPrivateKeyOk() (*string, bool)` + +GetPrivateKeyOk returns a tuple with the PrivateKey field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPrivateKey + +`func (o *DtoSshRevealResponse) SetPrivateKey(v string)` + +SetPrivateKey sets PrivateKey field to given value. + +### HasPrivateKey + +`func (o *DtoSshRevealResponse) HasPrivateKey() bool` + +HasPrivateKey returns a boolean if a field has been set. + +### GetPublicKey + +`func (o *DtoSshRevealResponse) GetPublicKey() string` + +GetPublicKey returns the PublicKey field if non-nil, zero value otherwise. + +### GetPublicKeyOk + +`func (o *DtoSshRevealResponse) GetPublicKeyOk() (*string, bool)` + +GetPublicKeyOk returns a tuple with the PublicKey field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPublicKey + +`func (o *DtoSshRevealResponse) SetPublicKey(v string)` + +SetPublicKey sets PublicKey field to given value. + +### HasPublicKey + +`func (o *DtoSshRevealResponse) HasPublicKey() bool` + +HasPublicKey returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *DtoSshRevealResponse) GetUpdatedAt() string` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *DtoSshRevealResponse) GetUpdatedAtOk() (*string, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *DtoSshRevealResponse) SetUpdatedAt(v string)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *DtoSshRevealResponse) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoTaintResponse.md b/sdk/go/docs/DtoTaintResponse.md new file mode 100644 index 0000000..172857a --- /dev/null +++ b/sdk/go/docs/DtoTaintResponse.md @@ -0,0 +1,134 @@ +# DtoTaintResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Effect** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | | [optional] +**Key** | Pointer to **string** | | [optional] +**Value** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoTaintResponse + +`func NewDtoTaintResponse() *DtoTaintResponse` + +NewDtoTaintResponse instantiates a new DtoTaintResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoTaintResponseWithDefaults + +`func NewDtoTaintResponseWithDefaults() *DtoTaintResponse` + +NewDtoTaintResponseWithDefaults instantiates a new DtoTaintResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetEffect + +`func (o *DtoTaintResponse) GetEffect() string` + +GetEffect returns the Effect field if non-nil, zero value otherwise. + +### GetEffectOk + +`func (o *DtoTaintResponse) GetEffectOk() (*string, bool)` + +GetEffectOk returns a tuple with the Effect field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEffect + +`func (o *DtoTaintResponse) SetEffect(v string)` + +SetEffect sets Effect field to given value. + +### HasEffect + +`func (o *DtoTaintResponse) HasEffect() bool` + +HasEffect returns a boolean if a field has been set. + +### GetId + +`func (o *DtoTaintResponse) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *DtoTaintResponse) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *DtoTaintResponse) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *DtoTaintResponse) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetKey + +`func (o *DtoTaintResponse) GetKey() string` + +GetKey returns the Key field if non-nil, zero value otherwise. + +### GetKeyOk + +`func (o *DtoTaintResponse) GetKeyOk() (*string, bool)` + +GetKeyOk returns a tuple with the Key field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKey + +`func (o *DtoTaintResponse) SetKey(v string)` + +SetKey sets Key field to given value. + +### HasKey + +`func (o *DtoTaintResponse) HasKey() bool` + +HasKey returns a boolean if a field has been set. + +### GetValue + +`func (o *DtoTaintResponse) GetValue() string` + +GetValue returns the Value field if non-nil, zero value otherwise. + +### GetValueOk + +`func (o *DtoTaintResponse) GetValueOk() (*string, bool)` + +GetValueOk returns a tuple with the Value field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetValue + +`func (o *DtoTaintResponse) SetValue(v string)` + +SetValue sets Value field to given value. + +### HasValue + +`func (o *DtoTaintResponse) HasValue() bool` + +HasValue returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoTokenPair.md b/sdk/go/docs/DtoTokenPair.md new file mode 100644 index 0000000..4325a37 --- /dev/null +++ b/sdk/go/docs/DtoTokenPair.md @@ -0,0 +1,134 @@ +# DtoTokenPair + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AccessToken** | Pointer to **string** | | [optional] +**ExpiresIn** | Pointer to **int32** | | [optional] +**RefreshToken** | Pointer to **string** | | [optional] +**TokenType** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoTokenPair + +`func NewDtoTokenPair() *DtoTokenPair` + +NewDtoTokenPair instantiates a new DtoTokenPair object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoTokenPairWithDefaults + +`func NewDtoTokenPairWithDefaults() *DtoTokenPair` + +NewDtoTokenPairWithDefaults instantiates a new DtoTokenPair object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetAccessToken + +`func (o *DtoTokenPair) GetAccessToken() string` + +GetAccessToken returns the AccessToken field if non-nil, zero value otherwise. + +### GetAccessTokenOk + +`func (o *DtoTokenPair) GetAccessTokenOk() (*string, bool)` + +GetAccessTokenOk returns a tuple with the AccessToken field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAccessToken + +`func (o *DtoTokenPair) SetAccessToken(v string)` + +SetAccessToken sets AccessToken field to given value. + +### HasAccessToken + +`func (o *DtoTokenPair) HasAccessToken() bool` + +HasAccessToken returns a boolean if a field has been set. + +### GetExpiresIn + +`func (o *DtoTokenPair) GetExpiresIn() int32` + +GetExpiresIn returns the ExpiresIn field if non-nil, zero value otherwise. + +### GetExpiresInOk + +`func (o *DtoTokenPair) GetExpiresInOk() (*int32, bool)` + +GetExpiresInOk returns a tuple with the ExpiresIn field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetExpiresIn + +`func (o *DtoTokenPair) SetExpiresIn(v int32)` + +SetExpiresIn sets ExpiresIn field to given value. + +### HasExpiresIn + +`func (o *DtoTokenPair) HasExpiresIn() bool` + +HasExpiresIn returns a boolean if a field has been set. + +### GetRefreshToken + +`func (o *DtoTokenPair) GetRefreshToken() string` + +GetRefreshToken returns the RefreshToken field if non-nil, zero value otherwise. + +### GetRefreshTokenOk + +`func (o *DtoTokenPair) GetRefreshTokenOk() (*string, bool)` + +GetRefreshTokenOk returns a tuple with the RefreshToken field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRefreshToken + +`func (o *DtoTokenPair) SetRefreshToken(v string)` + +SetRefreshToken sets RefreshToken field to given value. + +### HasRefreshToken + +`func (o *DtoTokenPair) HasRefreshToken() bool` + +HasRefreshToken returns a boolean if a field has been set. + +### GetTokenType + +`func (o *DtoTokenPair) GetTokenType() string` + +GetTokenType returns the TokenType field if non-nil, zero value otherwise. + +### GetTokenTypeOk + +`func (o *DtoTokenPair) GetTokenTypeOk() (*string, bool)` + +GetTokenTypeOk returns a tuple with the TokenType field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetTokenType + +`func (o *DtoTokenPair) SetTokenType(v string)` + +SetTokenType sets TokenType field to given value. + +### HasTokenType + +`func (o *DtoTokenPair) HasTokenType() bool` + +HasTokenType returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoUpdateServerRequest.md b/sdk/go/docs/DtoUpdateServerRequest.md new file mode 100644 index 0000000..3fc17b7 --- /dev/null +++ b/sdk/go/docs/DtoUpdateServerRequest.md @@ -0,0 +1,212 @@ +# DtoUpdateServerRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Hostname** | Pointer to **string** | | [optional] +**PrivateIpAddress** | Pointer to **string** | | [optional] +**PublicIpAddress** | Pointer to **string** | | [optional] +**Role** | Pointer to **string** | | [optional] +**SshKeyId** | Pointer to **string** | | [optional] +**SshUser** | Pointer to **string** | | [optional] +**Status** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoUpdateServerRequest + +`func NewDtoUpdateServerRequest() *DtoUpdateServerRequest` + +NewDtoUpdateServerRequest instantiates a new DtoUpdateServerRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoUpdateServerRequestWithDefaults + +`func NewDtoUpdateServerRequestWithDefaults() *DtoUpdateServerRequest` + +NewDtoUpdateServerRequestWithDefaults instantiates a new DtoUpdateServerRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetHostname + +`func (o *DtoUpdateServerRequest) GetHostname() string` + +GetHostname returns the Hostname field if non-nil, zero value otherwise. + +### GetHostnameOk + +`func (o *DtoUpdateServerRequest) GetHostnameOk() (*string, bool)` + +GetHostnameOk returns a tuple with the Hostname field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetHostname + +`func (o *DtoUpdateServerRequest) SetHostname(v string)` + +SetHostname sets Hostname field to given value. + +### HasHostname + +`func (o *DtoUpdateServerRequest) HasHostname() bool` + +HasHostname returns a boolean if a field has been set. + +### GetPrivateIpAddress + +`func (o *DtoUpdateServerRequest) GetPrivateIpAddress() string` + +GetPrivateIpAddress returns the PrivateIpAddress field if non-nil, zero value otherwise. + +### GetPrivateIpAddressOk + +`func (o *DtoUpdateServerRequest) GetPrivateIpAddressOk() (*string, bool)` + +GetPrivateIpAddressOk returns a tuple with the PrivateIpAddress field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPrivateIpAddress + +`func (o *DtoUpdateServerRequest) SetPrivateIpAddress(v string)` + +SetPrivateIpAddress sets PrivateIpAddress field to given value. + +### HasPrivateIpAddress + +`func (o *DtoUpdateServerRequest) HasPrivateIpAddress() bool` + +HasPrivateIpAddress returns a boolean if a field has been set. + +### GetPublicIpAddress + +`func (o *DtoUpdateServerRequest) GetPublicIpAddress() string` + +GetPublicIpAddress returns the PublicIpAddress field if non-nil, zero value otherwise. + +### GetPublicIpAddressOk + +`func (o *DtoUpdateServerRequest) GetPublicIpAddressOk() (*string, bool)` + +GetPublicIpAddressOk returns a tuple with the PublicIpAddress field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPublicIpAddress + +`func (o *DtoUpdateServerRequest) SetPublicIpAddress(v string)` + +SetPublicIpAddress sets PublicIpAddress field to given value. + +### HasPublicIpAddress + +`func (o *DtoUpdateServerRequest) HasPublicIpAddress() bool` + +HasPublicIpAddress returns a boolean if a field has been set. + +### GetRole + +`func (o *DtoUpdateServerRequest) GetRole() string` + +GetRole returns the Role field if non-nil, zero value otherwise. + +### GetRoleOk + +`func (o *DtoUpdateServerRequest) GetRoleOk() (*string, bool)` + +GetRoleOk returns a tuple with the Role field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRole + +`func (o *DtoUpdateServerRequest) SetRole(v string)` + +SetRole sets Role field to given value. + +### HasRole + +`func (o *DtoUpdateServerRequest) HasRole() bool` + +HasRole returns a boolean if a field has been set. + +### GetSshKeyId + +`func (o *DtoUpdateServerRequest) GetSshKeyId() string` + +GetSshKeyId returns the SshKeyId field if non-nil, zero value otherwise. + +### GetSshKeyIdOk + +`func (o *DtoUpdateServerRequest) GetSshKeyIdOk() (*string, bool)` + +GetSshKeyIdOk returns a tuple with the SshKeyId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSshKeyId + +`func (o *DtoUpdateServerRequest) SetSshKeyId(v string)` + +SetSshKeyId sets SshKeyId field to given value. + +### HasSshKeyId + +`func (o *DtoUpdateServerRequest) HasSshKeyId() bool` + +HasSshKeyId returns a boolean if a field has been set. + +### GetSshUser + +`func (o *DtoUpdateServerRequest) GetSshUser() string` + +GetSshUser returns the SshUser field if non-nil, zero value otherwise. + +### GetSshUserOk + +`func (o *DtoUpdateServerRequest) GetSshUserOk() (*string, bool)` + +GetSshUserOk returns a tuple with the SshUser field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSshUser + +`func (o *DtoUpdateServerRequest) SetSshUser(v string)` + +SetSshUser sets SshUser field to given value. + +### HasSshUser + +`func (o *DtoUpdateServerRequest) HasSshUser() bool` + +HasSshUser returns a boolean if a field has been set. + +### GetStatus + +`func (o *DtoUpdateServerRequest) GetStatus() string` + +GetStatus returns the Status field if non-nil, zero value otherwise. + +### GetStatusOk + +`func (o *DtoUpdateServerRequest) GetStatusOk() (*string, bool)` + +GetStatusOk returns a tuple with the Status field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetStatus + +`func (o *DtoUpdateServerRequest) SetStatus(v string)` + +SetStatus sets Status field to given value. + +### HasStatus + +`func (o *DtoUpdateServerRequest) HasStatus() bool` + +HasStatus returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/DtoUpdateTaintRequest.md b/sdk/go/docs/DtoUpdateTaintRequest.md new file mode 100644 index 0000000..e726d23 --- /dev/null +++ b/sdk/go/docs/DtoUpdateTaintRequest.md @@ -0,0 +1,108 @@ +# DtoUpdateTaintRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Effect** | Pointer to **string** | | [optional] +**Key** | Pointer to **string** | | [optional] +**Value** | Pointer to **string** | | [optional] + +## Methods + +### NewDtoUpdateTaintRequest + +`func NewDtoUpdateTaintRequest() *DtoUpdateTaintRequest` + +NewDtoUpdateTaintRequest instantiates a new DtoUpdateTaintRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewDtoUpdateTaintRequestWithDefaults + +`func NewDtoUpdateTaintRequestWithDefaults() *DtoUpdateTaintRequest` + +NewDtoUpdateTaintRequestWithDefaults instantiates a new DtoUpdateTaintRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetEffect + +`func (o *DtoUpdateTaintRequest) GetEffect() string` + +GetEffect returns the Effect field if non-nil, zero value otherwise. + +### GetEffectOk + +`func (o *DtoUpdateTaintRequest) GetEffectOk() (*string, bool)` + +GetEffectOk returns a tuple with the Effect field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEffect + +`func (o *DtoUpdateTaintRequest) SetEffect(v string)` + +SetEffect sets Effect field to given value. + +### HasEffect + +`func (o *DtoUpdateTaintRequest) HasEffect() bool` + +HasEffect returns a boolean if a field has been set. + +### GetKey + +`func (o *DtoUpdateTaintRequest) GetKey() string` + +GetKey returns the Key field if non-nil, zero value otherwise. + +### GetKeyOk + +`func (o *DtoUpdateTaintRequest) GetKeyOk() (*string, bool)` + +GetKeyOk returns a tuple with the Key field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKey + +`func (o *DtoUpdateTaintRequest) SetKey(v string)` + +SetKey sets Key field to given value. + +### HasKey + +`func (o *DtoUpdateTaintRequest) HasKey() bool` + +HasKey returns a boolean if a field has been set. + +### GetValue + +`func (o *DtoUpdateTaintRequest) GetValue() string` + +GetValue returns the Value field if non-nil, zero value otherwise. + +### GetValueOk + +`func (o *DtoUpdateTaintRequest) GetValueOk() (*string, bool)` + +GetValueOk returns a tuple with the Value field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetValue + +`func (o *DtoUpdateTaintRequest) SetValue(v string)` + +SetValue sets Value field to given value. + +### HasValue + +`func (o *DtoUpdateTaintRequest) HasValue() bool` + +HasValue returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersCreateUserKeyRequest.md b/sdk/go/docs/HandlersCreateUserKeyRequest.md new file mode 100644 index 0000000..0564e49 --- /dev/null +++ b/sdk/go/docs/HandlersCreateUserKeyRequest.md @@ -0,0 +1,82 @@ +# HandlersCreateUserKeyRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ExpiresInHours** | Pointer to **int32** | optional TTL | [optional] +**Name** | Pointer to **string** | | [optional] + +## Methods + +### NewHandlersCreateUserKeyRequest + +`func NewHandlersCreateUserKeyRequest() *HandlersCreateUserKeyRequest` + +NewHandlersCreateUserKeyRequest instantiates a new HandlersCreateUserKeyRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersCreateUserKeyRequestWithDefaults + +`func NewHandlersCreateUserKeyRequestWithDefaults() *HandlersCreateUserKeyRequest` + +NewHandlersCreateUserKeyRequestWithDefaults instantiates a new HandlersCreateUserKeyRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetExpiresInHours + +`func (o *HandlersCreateUserKeyRequest) GetExpiresInHours() int32` + +GetExpiresInHours returns the ExpiresInHours field if non-nil, zero value otherwise. + +### GetExpiresInHoursOk + +`func (o *HandlersCreateUserKeyRequest) GetExpiresInHoursOk() (*int32, bool)` + +GetExpiresInHoursOk returns a tuple with the ExpiresInHours field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetExpiresInHours + +`func (o *HandlersCreateUserKeyRequest) SetExpiresInHours(v int32)` + +SetExpiresInHours sets ExpiresInHours field to given value. + +### HasExpiresInHours + +`func (o *HandlersCreateUserKeyRequest) HasExpiresInHours() bool` + +HasExpiresInHours returns a boolean if a field has been set. + +### GetName + +`func (o *HandlersCreateUserKeyRequest) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *HandlersCreateUserKeyRequest) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *HandlersCreateUserKeyRequest) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *HandlersCreateUserKeyRequest) HasName() bool` + +HasName returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersMeResponse.md b/sdk/go/docs/HandlersMeResponse.md new file mode 100644 index 0000000..e80293b --- /dev/null +++ b/sdk/go/docs/HandlersMeResponse.md @@ -0,0 +1,264 @@ +# HandlersMeResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AvatarUrl** | Pointer to **string** | | [optional] +**CreatedAt** | Pointer to **time.Time** | | [optional] +**DisplayName** | Pointer to **string** | | [optional] +**Emails** | Pointer to [**[]ModelsUserEmail**](ModelsUserEmail.md) | | [optional] +**Id** | Pointer to **string** | example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 | [optional] +**IsDisabled** | Pointer to **bool** | | [optional] +**Organizations** | Pointer to [**[]ModelsOrganization**](ModelsOrganization.md) | | [optional] +**PrimaryEmail** | Pointer to **string** | | [optional] +**UpdatedAt** | Pointer to **time.Time** | | [optional] + +## Methods + +### NewHandlersMeResponse + +`func NewHandlersMeResponse() *HandlersMeResponse` + +NewHandlersMeResponse instantiates a new HandlersMeResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersMeResponseWithDefaults + +`func NewHandlersMeResponseWithDefaults() *HandlersMeResponse` + +NewHandlersMeResponseWithDefaults instantiates a new HandlersMeResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetAvatarUrl + +`func (o *HandlersMeResponse) GetAvatarUrl() string` + +GetAvatarUrl returns the AvatarUrl field if non-nil, zero value otherwise. + +### GetAvatarUrlOk + +`func (o *HandlersMeResponse) GetAvatarUrlOk() (*string, bool)` + +GetAvatarUrlOk returns a tuple with the AvatarUrl field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAvatarUrl + +`func (o *HandlersMeResponse) SetAvatarUrl(v string)` + +SetAvatarUrl sets AvatarUrl field to given value. + +### HasAvatarUrl + +`func (o *HandlersMeResponse) HasAvatarUrl() bool` + +HasAvatarUrl returns a boolean if a field has been set. + +### GetCreatedAt + +`func (o *HandlersMeResponse) GetCreatedAt() time.Time` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *HandlersMeResponse) GetCreatedAtOk() (*time.Time, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *HandlersMeResponse) SetCreatedAt(v time.Time)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *HandlersMeResponse) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetDisplayName + +`func (o *HandlersMeResponse) GetDisplayName() string` + +GetDisplayName returns the DisplayName field if non-nil, zero value otherwise. + +### GetDisplayNameOk + +`func (o *HandlersMeResponse) GetDisplayNameOk() (*string, bool)` + +GetDisplayNameOk returns a tuple with the DisplayName field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDisplayName + +`func (o *HandlersMeResponse) SetDisplayName(v string)` + +SetDisplayName sets DisplayName field to given value. + +### HasDisplayName + +`func (o *HandlersMeResponse) HasDisplayName() bool` + +HasDisplayName returns a boolean if a field has been set. + +### GetEmails + +`func (o *HandlersMeResponse) GetEmails() []ModelsUserEmail` + +GetEmails returns the Emails field if non-nil, zero value otherwise. + +### GetEmailsOk + +`func (o *HandlersMeResponse) GetEmailsOk() (*[]ModelsUserEmail, bool)` + +GetEmailsOk returns a tuple with the Emails field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEmails + +`func (o *HandlersMeResponse) SetEmails(v []ModelsUserEmail)` + +SetEmails sets Emails field to given value. + +### HasEmails + +`func (o *HandlersMeResponse) HasEmails() bool` + +HasEmails returns a boolean if a field has been set. + +### GetId + +`func (o *HandlersMeResponse) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *HandlersMeResponse) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *HandlersMeResponse) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *HandlersMeResponse) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetIsDisabled + +`func (o *HandlersMeResponse) GetIsDisabled() bool` + +GetIsDisabled returns the IsDisabled field if non-nil, zero value otherwise. + +### GetIsDisabledOk + +`func (o *HandlersMeResponse) GetIsDisabledOk() (*bool, bool)` + +GetIsDisabledOk returns a tuple with the IsDisabled field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetIsDisabled + +`func (o *HandlersMeResponse) SetIsDisabled(v bool)` + +SetIsDisabled sets IsDisabled field to given value. + +### HasIsDisabled + +`func (o *HandlersMeResponse) HasIsDisabled() bool` + +HasIsDisabled returns a boolean if a field has been set. + +### GetOrganizations + +`func (o *HandlersMeResponse) GetOrganizations() []ModelsOrganization` + +GetOrganizations returns the Organizations field if non-nil, zero value otherwise. + +### GetOrganizationsOk + +`func (o *HandlersMeResponse) GetOrganizationsOk() (*[]ModelsOrganization, bool)` + +GetOrganizationsOk returns a tuple with the Organizations field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOrganizations + +`func (o *HandlersMeResponse) SetOrganizations(v []ModelsOrganization)` + +SetOrganizations sets Organizations field to given value. + +### HasOrganizations + +`func (o *HandlersMeResponse) HasOrganizations() bool` + +HasOrganizations returns a boolean if a field has been set. + +### GetPrimaryEmail + +`func (o *HandlersMeResponse) GetPrimaryEmail() string` + +GetPrimaryEmail returns the PrimaryEmail field if non-nil, zero value otherwise. + +### GetPrimaryEmailOk + +`func (o *HandlersMeResponse) GetPrimaryEmailOk() (*string, bool)` + +GetPrimaryEmailOk returns a tuple with the PrimaryEmail field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPrimaryEmail + +`func (o *HandlersMeResponse) SetPrimaryEmail(v string)` + +SetPrimaryEmail sets PrimaryEmail field to given value. + +### HasPrimaryEmail + +`func (o *HandlersMeResponse) HasPrimaryEmail() bool` + +HasPrimaryEmail returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *HandlersMeResponse) GetUpdatedAt() time.Time` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *HandlersMeResponse) GetUpdatedAtOk() (*time.Time, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *HandlersMeResponse) SetUpdatedAt(v time.Time)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *HandlersMeResponse) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersMemberOut.md b/sdk/go/docs/HandlersMemberOut.md new file mode 100644 index 0000000..a865676 --- /dev/null +++ b/sdk/go/docs/HandlersMemberOut.md @@ -0,0 +1,108 @@ +# HandlersMemberOut + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Email** | Pointer to **string** | | [optional] +**Role** | Pointer to **string** | owner/admin/member | [optional] +**UserId** | Pointer to **string** | | [optional] + +## Methods + +### NewHandlersMemberOut + +`func NewHandlersMemberOut() *HandlersMemberOut` + +NewHandlersMemberOut instantiates a new HandlersMemberOut object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersMemberOutWithDefaults + +`func NewHandlersMemberOutWithDefaults() *HandlersMemberOut` + +NewHandlersMemberOutWithDefaults instantiates a new HandlersMemberOut object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetEmail + +`func (o *HandlersMemberOut) GetEmail() string` + +GetEmail returns the Email field if non-nil, zero value otherwise. + +### GetEmailOk + +`func (o *HandlersMemberOut) GetEmailOk() (*string, bool)` + +GetEmailOk returns a tuple with the Email field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEmail + +`func (o *HandlersMemberOut) SetEmail(v string)` + +SetEmail sets Email field to given value. + +### HasEmail + +`func (o *HandlersMemberOut) HasEmail() bool` + +HasEmail returns a boolean if a field has been set. + +### GetRole + +`func (o *HandlersMemberOut) GetRole() string` + +GetRole returns the Role field if non-nil, zero value otherwise. + +### GetRoleOk + +`func (o *HandlersMemberOut) GetRoleOk() (*string, bool)` + +GetRoleOk returns a tuple with the Role field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRole + +`func (o *HandlersMemberOut) SetRole(v string)` + +SetRole sets Role field to given value. + +### HasRole + +`func (o *HandlersMemberOut) HasRole() bool` + +HasRole returns a boolean if a field has been set. + +### GetUserId + +`func (o *HandlersMemberOut) GetUserId() string` + +GetUserId returns the UserId field if non-nil, zero value otherwise. + +### GetUserIdOk + +`func (o *HandlersMemberOut) GetUserIdOk() (*string, bool)` + +GetUserIdOk returns a tuple with the UserId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUserId + +`func (o *HandlersMemberOut) SetUserId(v string)` + +SetUserId sets UserId field to given value. + +### HasUserId + +`func (o *HandlersMemberOut) HasUserId() bool` + +HasUserId returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersMemberUpsertReq.md b/sdk/go/docs/HandlersMemberUpsertReq.md new file mode 100644 index 0000000..c2d9671 --- /dev/null +++ b/sdk/go/docs/HandlersMemberUpsertReq.md @@ -0,0 +1,82 @@ +# HandlersMemberUpsertReq + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Role** | Pointer to **string** | | [optional] +**UserId** | Pointer to **string** | | [optional] + +## Methods + +### NewHandlersMemberUpsertReq + +`func NewHandlersMemberUpsertReq() *HandlersMemberUpsertReq` + +NewHandlersMemberUpsertReq instantiates a new HandlersMemberUpsertReq object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersMemberUpsertReqWithDefaults + +`func NewHandlersMemberUpsertReqWithDefaults() *HandlersMemberUpsertReq` + +NewHandlersMemberUpsertReqWithDefaults instantiates a new HandlersMemberUpsertReq object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetRole + +`func (o *HandlersMemberUpsertReq) GetRole() string` + +GetRole returns the Role field if non-nil, zero value otherwise. + +### GetRoleOk + +`func (o *HandlersMemberUpsertReq) GetRoleOk() (*string, bool)` + +GetRoleOk returns a tuple with the Role field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRole + +`func (o *HandlersMemberUpsertReq) SetRole(v string)` + +SetRole sets Role field to given value. + +### HasRole + +`func (o *HandlersMemberUpsertReq) HasRole() bool` + +HasRole returns a boolean if a field has been set. + +### GetUserId + +`func (o *HandlersMemberUpsertReq) GetUserId() string` + +GetUserId returns the UserId field if non-nil, zero value otherwise. + +### GetUserIdOk + +`func (o *HandlersMemberUpsertReq) GetUserIdOk() (*string, bool)` + +GetUserIdOk returns a tuple with the UserId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUserId + +`func (o *HandlersMemberUpsertReq) SetUserId(v string)` + +SetUserId sets UserId field to given value. + +### HasUserId + +`func (o *HandlersMemberUpsertReq) HasUserId() bool` + +HasUserId returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersOrgCreateReq.md b/sdk/go/docs/HandlersOrgCreateReq.md new file mode 100644 index 0000000..07eea50 --- /dev/null +++ b/sdk/go/docs/HandlersOrgCreateReq.md @@ -0,0 +1,82 @@ +# HandlersOrgCreateReq + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Domain** | Pointer to **string** | | [optional] +**Name** | Pointer to **string** | | [optional] + +## Methods + +### NewHandlersOrgCreateReq + +`func NewHandlersOrgCreateReq() *HandlersOrgCreateReq` + +NewHandlersOrgCreateReq instantiates a new HandlersOrgCreateReq object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersOrgCreateReqWithDefaults + +`func NewHandlersOrgCreateReqWithDefaults() *HandlersOrgCreateReq` + +NewHandlersOrgCreateReqWithDefaults instantiates a new HandlersOrgCreateReq object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetDomain + +`func (o *HandlersOrgCreateReq) GetDomain() string` + +GetDomain returns the Domain field if non-nil, zero value otherwise. + +### GetDomainOk + +`func (o *HandlersOrgCreateReq) GetDomainOk() (*string, bool)` + +GetDomainOk returns a tuple with the Domain field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDomain + +`func (o *HandlersOrgCreateReq) SetDomain(v string)` + +SetDomain sets Domain field to given value. + +### HasDomain + +`func (o *HandlersOrgCreateReq) HasDomain() bool` + +HasDomain returns a boolean if a field has been set. + +### GetName + +`func (o *HandlersOrgCreateReq) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *HandlersOrgCreateReq) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *HandlersOrgCreateReq) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *HandlersOrgCreateReq) HasName() bool` + +HasName returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersOrgKeyCreateReq.md b/sdk/go/docs/HandlersOrgKeyCreateReq.md new file mode 100644 index 0000000..f69d484 --- /dev/null +++ b/sdk/go/docs/HandlersOrgKeyCreateReq.md @@ -0,0 +1,82 @@ +# HandlersOrgKeyCreateReq + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ExpiresInHours** | Pointer to **int32** | | [optional] +**Name** | Pointer to **string** | | [optional] + +## Methods + +### NewHandlersOrgKeyCreateReq + +`func NewHandlersOrgKeyCreateReq() *HandlersOrgKeyCreateReq` + +NewHandlersOrgKeyCreateReq instantiates a new HandlersOrgKeyCreateReq object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersOrgKeyCreateReqWithDefaults + +`func NewHandlersOrgKeyCreateReqWithDefaults() *HandlersOrgKeyCreateReq` + +NewHandlersOrgKeyCreateReqWithDefaults instantiates a new HandlersOrgKeyCreateReq object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetExpiresInHours + +`func (o *HandlersOrgKeyCreateReq) GetExpiresInHours() int32` + +GetExpiresInHours returns the ExpiresInHours field if non-nil, zero value otherwise. + +### GetExpiresInHoursOk + +`func (o *HandlersOrgKeyCreateReq) GetExpiresInHoursOk() (*int32, bool)` + +GetExpiresInHoursOk returns a tuple with the ExpiresInHours field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetExpiresInHours + +`func (o *HandlersOrgKeyCreateReq) SetExpiresInHours(v int32)` + +SetExpiresInHours sets ExpiresInHours field to given value. + +### HasExpiresInHours + +`func (o *HandlersOrgKeyCreateReq) HasExpiresInHours() bool` + +HasExpiresInHours returns a boolean if a field has been set. + +### GetName + +`func (o *HandlersOrgKeyCreateReq) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *HandlersOrgKeyCreateReq) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *HandlersOrgKeyCreateReq) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *HandlersOrgKeyCreateReq) HasName() bool` + +HasName returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersOrgKeyCreateResp.md b/sdk/go/docs/HandlersOrgKeyCreateResp.md new file mode 100644 index 0000000..aa0fb3c --- /dev/null +++ b/sdk/go/docs/HandlersOrgKeyCreateResp.md @@ -0,0 +1,212 @@ +# HandlersOrgKeyCreateResp + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CreatedAt** | Pointer to **string** | | [optional] +**ExpiresAt** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | | [optional] +**Name** | Pointer to **string** | | [optional] +**OrgKey** | Pointer to **string** | shown once: | [optional] +**OrgSecret** | Pointer to **string** | shown once: | [optional] +**Scope** | Pointer to **string** | \"org\" | [optional] + +## Methods + +### NewHandlersOrgKeyCreateResp + +`func NewHandlersOrgKeyCreateResp() *HandlersOrgKeyCreateResp` + +NewHandlersOrgKeyCreateResp instantiates a new HandlersOrgKeyCreateResp object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersOrgKeyCreateRespWithDefaults + +`func NewHandlersOrgKeyCreateRespWithDefaults() *HandlersOrgKeyCreateResp` + +NewHandlersOrgKeyCreateRespWithDefaults instantiates a new HandlersOrgKeyCreateResp object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCreatedAt + +`func (o *HandlersOrgKeyCreateResp) GetCreatedAt() string` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *HandlersOrgKeyCreateResp) GetCreatedAtOk() (*string, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *HandlersOrgKeyCreateResp) SetCreatedAt(v string)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *HandlersOrgKeyCreateResp) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetExpiresAt + +`func (o *HandlersOrgKeyCreateResp) GetExpiresAt() string` + +GetExpiresAt returns the ExpiresAt field if non-nil, zero value otherwise. + +### GetExpiresAtOk + +`func (o *HandlersOrgKeyCreateResp) GetExpiresAtOk() (*string, bool)` + +GetExpiresAtOk returns a tuple with the ExpiresAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetExpiresAt + +`func (o *HandlersOrgKeyCreateResp) SetExpiresAt(v string)` + +SetExpiresAt sets ExpiresAt field to given value. + +### HasExpiresAt + +`func (o *HandlersOrgKeyCreateResp) HasExpiresAt() bool` + +HasExpiresAt returns a boolean if a field has been set. + +### GetId + +`func (o *HandlersOrgKeyCreateResp) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *HandlersOrgKeyCreateResp) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *HandlersOrgKeyCreateResp) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *HandlersOrgKeyCreateResp) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetName + +`func (o *HandlersOrgKeyCreateResp) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *HandlersOrgKeyCreateResp) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *HandlersOrgKeyCreateResp) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *HandlersOrgKeyCreateResp) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetOrgKey + +`func (o *HandlersOrgKeyCreateResp) GetOrgKey() string` + +GetOrgKey returns the OrgKey field if non-nil, zero value otherwise. + +### GetOrgKeyOk + +`func (o *HandlersOrgKeyCreateResp) GetOrgKeyOk() (*string, bool)` + +GetOrgKeyOk returns a tuple with the OrgKey field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOrgKey + +`func (o *HandlersOrgKeyCreateResp) SetOrgKey(v string)` + +SetOrgKey sets OrgKey field to given value. + +### HasOrgKey + +`func (o *HandlersOrgKeyCreateResp) HasOrgKey() bool` + +HasOrgKey returns a boolean if a field has been set. + +### GetOrgSecret + +`func (o *HandlersOrgKeyCreateResp) GetOrgSecret() string` + +GetOrgSecret returns the OrgSecret field if non-nil, zero value otherwise. + +### GetOrgSecretOk + +`func (o *HandlersOrgKeyCreateResp) GetOrgSecretOk() (*string, bool)` + +GetOrgSecretOk returns a tuple with the OrgSecret field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOrgSecret + +`func (o *HandlersOrgKeyCreateResp) SetOrgSecret(v string)` + +SetOrgSecret sets OrgSecret field to given value. + +### HasOrgSecret + +`func (o *HandlersOrgKeyCreateResp) HasOrgSecret() bool` + +HasOrgSecret returns a boolean if a field has been set. + +### GetScope + +`func (o *HandlersOrgKeyCreateResp) GetScope() string` + +GetScope returns the Scope field if non-nil, zero value otherwise. + +### GetScopeOk + +`func (o *HandlersOrgKeyCreateResp) GetScopeOk() (*string, bool)` + +GetScopeOk returns a tuple with the Scope field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetScope + +`func (o *HandlersOrgKeyCreateResp) SetScope(v string)` + +SetScope sets Scope field to given value. + +### HasScope + +`func (o *HandlersOrgKeyCreateResp) HasScope() bool` + +HasScope returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersOrgUpdateReq.md b/sdk/go/docs/HandlersOrgUpdateReq.md new file mode 100644 index 0000000..ff89ace --- /dev/null +++ b/sdk/go/docs/HandlersOrgUpdateReq.md @@ -0,0 +1,82 @@ +# HandlersOrgUpdateReq + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Domain** | Pointer to **string** | | [optional] +**Name** | Pointer to **string** | | [optional] + +## Methods + +### NewHandlersOrgUpdateReq + +`func NewHandlersOrgUpdateReq() *HandlersOrgUpdateReq` + +NewHandlersOrgUpdateReq instantiates a new HandlersOrgUpdateReq object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersOrgUpdateReqWithDefaults + +`func NewHandlersOrgUpdateReqWithDefaults() *HandlersOrgUpdateReq` + +NewHandlersOrgUpdateReqWithDefaults instantiates a new HandlersOrgUpdateReq object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetDomain + +`func (o *HandlersOrgUpdateReq) GetDomain() string` + +GetDomain returns the Domain field if non-nil, zero value otherwise. + +### GetDomainOk + +`func (o *HandlersOrgUpdateReq) GetDomainOk() (*string, bool)` + +GetDomainOk returns a tuple with the Domain field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDomain + +`func (o *HandlersOrgUpdateReq) SetDomain(v string)` + +SetDomain sets Domain field to given value. + +### HasDomain + +`func (o *HandlersOrgUpdateReq) HasDomain() bool` + +HasDomain returns a boolean if a field has been set. + +### GetName + +`func (o *HandlersOrgUpdateReq) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *HandlersOrgUpdateReq) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *HandlersOrgUpdateReq) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *HandlersOrgUpdateReq) HasName() bool` + +HasName returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersUpdateMeRequest.md b/sdk/go/docs/HandlersUpdateMeRequest.md new file mode 100644 index 0000000..eda195e --- /dev/null +++ b/sdk/go/docs/HandlersUpdateMeRequest.md @@ -0,0 +1,56 @@ +# HandlersUpdateMeRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**DisplayName** | Pointer to **string** | | [optional] + +## Methods + +### NewHandlersUpdateMeRequest + +`func NewHandlersUpdateMeRequest() *HandlersUpdateMeRequest` + +NewHandlersUpdateMeRequest instantiates a new HandlersUpdateMeRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersUpdateMeRequestWithDefaults + +`func NewHandlersUpdateMeRequestWithDefaults() *HandlersUpdateMeRequest` + +NewHandlersUpdateMeRequestWithDefaults instantiates a new HandlersUpdateMeRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetDisplayName + +`func (o *HandlersUpdateMeRequest) GetDisplayName() string` + +GetDisplayName returns the DisplayName field if non-nil, zero value otherwise. + +### GetDisplayNameOk + +`func (o *HandlersUpdateMeRequest) GetDisplayNameOk() (*string, bool)` + +GetDisplayNameOk returns a tuple with the DisplayName field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDisplayName + +`func (o *HandlersUpdateMeRequest) SetDisplayName(v string)` + +SetDisplayName sets DisplayName field to given value. + +### HasDisplayName + +`func (o *HandlersUpdateMeRequest) HasDisplayName() bool` + +HasDisplayName returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/HandlersUserAPIKeyOut.md b/sdk/go/docs/HandlersUserAPIKeyOut.md new file mode 100644 index 0000000..90d3e6f --- /dev/null +++ b/sdk/go/docs/HandlersUserAPIKeyOut.md @@ -0,0 +1,212 @@ +# HandlersUserAPIKeyOut + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CreatedAt** | Pointer to **string** | | [optional] +**ExpiresAt** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | | [optional] +**LastUsedAt** | Pointer to **string** | | [optional] +**Name** | Pointer to **string** | | [optional] +**Plain** | Pointer to **string** | Shown only on create: | [optional] +**Scope** | Pointer to **string** | \"user\" | [optional] + +## Methods + +### NewHandlersUserAPIKeyOut + +`func NewHandlersUserAPIKeyOut() *HandlersUserAPIKeyOut` + +NewHandlersUserAPIKeyOut instantiates a new HandlersUserAPIKeyOut object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewHandlersUserAPIKeyOutWithDefaults + +`func NewHandlersUserAPIKeyOutWithDefaults() *HandlersUserAPIKeyOut` + +NewHandlersUserAPIKeyOutWithDefaults instantiates a new HandlersUserAPIKeyOut object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCreatedAt + +`func (o *HandlersUserAPIKeyOut) GetCreatedAt() string` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *HandlersUserAPIKeyOut) GetCreatedAtOk() (*string, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *HandlersUserAPIKeyOut) SetCreatedAt(v string)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *HandlersUserAPIKeyOut) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetExpiresAt + +`func (o *HandlersUserAPIKeyOut) GetExpiresAt() string` + +GetExpiresAt returns the ExpiresAt field if non-nil, zero value otherwise. + +### GetExpiresAtOk + +`func (o *HandlersUserAPIKeyOut) GetExpiresAtOk() (*string, bool)` + +GetExpiresAtOk returns a tuple with the ExpiresAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetExpiresAt + +`func (o *HandlersUserAPIKeyOut) SetExpiresAt(v string)` + +SetExpiresAt sets ExpiresAt field to given value. + +### HasExpiresAt + +`func (o *HandlersUserAPIKeyOut) HasExpiresAt() bool` + +HasExpiresAt returns a boolean if a field has been set. + +### GetId + +`func (o *HandlersUserAPIKeyOut) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *HandlersUserAPIKeyOut) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *HandlersUserAPIKeyOut) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *HandlersUserAPIKeyOut) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetLastUsedAt + +`func (o *HandlersUserAPIKeyOut) GetLastUsedAt() string` + +GetLastUsedAt returns the LastUsedAt field if non-nil, zero value otherwise. + +### GetLastUsedAtOk + +`func (o *HandlersUserAPIKeyOut) GetLastUsedAtOk() (*string, bool)` + +GetLastUsedAtOk returns a tuple with the LastUsedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastUsedAt + +`func (o *HandlersUserAPIKeyOut) SetLastUsedAt(v string)` + +SetLastUsedAt sets LastUsedAt field to given value. + +### HasLastUsedAt + +`func (o *HandlersUserAPIKeyOut) HasLastUsedAt() bool` + +HasLastUsedAt returns a boolean if a field has been set. + +### GetName + +`func (o *HandlersUserAPIKeyOut) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *HandlersUserAPIKeyOut) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *HandlersUserAPIKeyOut) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *HandlersUserAPIKeyOut) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetPlain + +`func (o *HandlersUserAPIKeyOut) GetPlain() string` + +GetPlain returns the Plain field if non-nil, zero value otherwise. + +### GetPlainOk + +`func (o *HandlersUserAPIKeyOut) GetPlainOk() (*string, bool)` + +GetPlainOk returns a tuple with the Plain field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPlain + +`func (o *HandlersUserAPIKeyOut) SetPlain(v string)` + +SetPlain sets Plain field to given value. + +### HasPlain + +`func (o *HandlersUserAPIKeyOut) HasPlain() bool` + +HasPlain returns a boolean if a field has been set. + +### GetScope + +`func (o *HandlersUserAPIKeyOut) GetScope() string` + +GetScope returns the Scope field if non-nil, zero value otherwise. + +### GetScopeOk + +`func (o *HandlersUserAPIKeyOut) GetScopeOk() (*string, bool)` + +GetScopeOk returns a tuple with the Scope field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetScope + +`func (o *HandlersUserAPIKeyOut) SetScope(v string)` + +SetScope sets Scope field to given value. + +### HasScope + +`func (o *HandlersUserAPIKeyOut) HasScope() bool` + +HasScope returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/MeAPI.md b/sdk/go/docs/MeAPI.md new file mode 100644 index 0000000..bbebe60 --- /dev/null +++ b/sdk/go/docs/MeAPI.md @@ -0,0 +1,133 @@ +# \MeAPI + +All URIs are relative to *http://localhost:8080/api/v1* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**GetMe**](MeAPI.md#GetMe) | **Get** /me | Get current user profile +[**UpdateMe**](MeAPI.md#UpdateMe) | **Patch** /me | Update current user profile + + + +## GetMe + +> HandlersMeResponse GetMe(ctx).Execute() + +Get current user profile + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.MeAPI.GetMe(context.Background()).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `MeAPI.GetMe``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetMe`: HandlersMeResponse + fmt.Fprintf(os.Stdout, "Response from `MeAPI.GetMe`: %v\n", resp) +} +``` + +### Path Parameters + +This endpoint does not need any parameter. + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetMeRequest struct via the builder pattern + + +### Return type + +[**HandlersMeResponse**](HandlersMeResponse.md) + +### Authorization + +[ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## UpdateMe + +> ModelsUser UpdateMe(ctx).Body(body).Execute() + +Update current user profile + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + body := *openapiclient.NewHandlersUpdateMeRequest() // HandlersUpdateMeRequest | Patch profile + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.MeAPI.UpdateMe(context.Background()).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `MeAPI.UpdateMe``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `UpdateMe`: ModelsUser + fmt.Fprintf(os.Stdout, "Response from `MeAPI.UpdateMe`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiUpdateMeRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**HandlersUpdateMeRequest**](HandlersUpdateMeRequest.md) | Patch profile | + +### Return type + +[**ModelsUser**](ModelsUser.md) + +### Authorization + +[ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/sdk/go/docs/MeAPIKeysAPI.md b/sdk/go/docs/MeAPIKeysAPI.md new file mode 100644 index 0000000..033458c --- /dev/null +++ b/sdk/go/docs/MeAPIKeysAPI.md @@ -0,0 +1,202 @@ +# \MeAPIKeysAPI + +All URIs are relative to *http://localhost:8080/api/v1* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**CreateUserAPIKey**](MeAPIKeysAPI.md#CreateUserAPIKey) | **Post** /me/api-keys | Create a new user API key +[**DeleteUserAPIKey**](MeAPIKeysAPI.md#DeleteUserAPIKey) | **Delete** /me/api-keys/{id} | Delete a user API key +[**ListUserAPIKeys**](MeAPIKeysAPI.md#ListUserAPIKeys) | **Get** /me/api-keys | List my API keys + + + +## CreateUserAPIKey + +> HandlersUserAPIKeyOut CreateUserAPIKey(ctx).Body(body).Execute() + +Create a new user API key + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + body := *openapiclient.NewHandlersCreateUserKeyRequest() // HandlersCreateUserKeyRequest | Key options + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.MeAPIKeysAPI.CreateUserAPIKey(context.Background()).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `MeAPIKeysAPI.CreateUserAPIKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `CreateUserAPIKey`: HandlersUserAPIKeyOut + fmt.Fprintf(os.Stdout, "Response from `MeAPIKeysAPI.CreateUserAPIKey`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiCreateUserAPIKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**HandlersCreateUserKeyRequest**](HandlersCreateUserKeyRequest.md) | Key options | + +### Return type + +[**HandlersUserAPIKeyOut**](HandlersUserAPIKeyOut.md) + +### Authorization + +[ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## DeleteUserAPIKey + +> DeleteUserAPIKey(ctx, id).Execute() + +Delete a user API key + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Key ID (UUID) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.MeAPIKeysAPI.DeleteUserAPIKey(context.Background(), id).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `MeAPIKeysAPI.DeleteUserAPIKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Key ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiDeleteUserAPIKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListUserAPIKeys + +> []HandlersUserAPIKeyOut ListUserAPIKeys(ctx).Execute() + +List my API keys + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.MeAPIKeysAPI.ListUserAPIKeys(context.Background()).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `MeAPIKeysAPI.ListUserAPIKeys``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListUserAPIKeys`: []HandlersUserAPIKeyOut + fmt.Fprintf(os.Stdout, "Response from `MeAPIKeysAPI.ListUserAPIKeys`: %v\n", resp) +} +``` + +### Path Parameters + +This endpoint does not need any parameter. + +### Other Parameters + +Other parameters are passed through a pointer to a apiListUserAPIKeysRequest struct via the builder pattern + + +### Return type + +[**[]HandlersUserAPIKeyOut**](HandlersUserAPIKeyOut.md) + +### Authorization + +[ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/sdk/go/docs/ModelsAPIKey.md b/sdk/go/docs/ModelsAPIKey.md new file mode 100644 index 0000000..d5db33e --- /dev/null +++ b/sdk/go/docs/ModelsAPIKey.md @@ -0,0 +1,316 @@ +# ModelsAPIKey + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CreatedAt** | Pointer to **time.Time** | | [optional] +**ExpiresAt** | Pointer to **time.Time** | | [optional] +**Id** | Pointer to **string** | | [optional] +**LastUsedAt** | Pointer to **time.Time** | | [optional] +**Name** | Pointer to **string** | | [optional] +**OrgId** | Pointer to **string** | | [optional] +**Prefix** | Pointer to **string** | | [optional] +**Revoked** | Pointer to **bool** | | [optional] +**Scope** | Pointer to **string** | | [optional] +**UpdatedAt** | Pointer to **time.Time** | | [optional] +**UserId** | Pointer to **string** | | [optional] + +## Methods + +### NewModelsAPIKey + +`func NewModelsAPIKey() *ModelsAPIKey` + +NewModelsAPIKey instantiates a new ModelsAPIKey object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewModelsAPIKeyWithDefaults + +`func NewModelsAPIKeyWithDefaults() *ModelsAPIKey` + +NewModelsAPIKeyWithDefaults instantiates a new ModelsAPIKey object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCreatedAt + +`func (o *ModelsAPIKey) GetCreatedAt() time.Time` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *ModelsAPIKey) GetCreatedAtOk() (*time.Time, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *ModelsAPIKey) SetCreatedAt(v time.Time)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *ModelsAPIKey) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetExpiresAt + +`func (o *ModelsAPIKey) GetExpiresAt() time.Time` + +GetExpiresAt returns the ExpiresAt field if non-nil, zero value otherwise. + +### GetExpiresAtOk + +`func (o *ModelsAPIKey) GetExpiresAtOk() (*time.Time, bool)` + +GetExpiresAtOk returns a tuple with the ExpiresAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetExpiresAt + +`func (o *ModelsAPIKey) SetExpiresAt(v time.Time)` + +SetExpiresAt sets ExpiresAt field to given value. + +### HasExpiresAt + +`func (o *ModelsAPIKey) HasExpiresAt() bool` + +HasExpiresAt returns a boolean if a field has been set. + +### GetId + +`func (o *ModelsAPIKey) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *ModelsAPIKey) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *ModelsAPIKey) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *ModelsAPIKey) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetLastUsedAt + +`func (o *ModelsAPIKey) GetLastUsedAt() time.Time` + +GetLastUsedAt returns the LastUsedAt field if non-nil, zero value otherwise. + +### GetLastUsedAtOk + +`func (o *ModelsAPIKey) GetLastUsedAtOk() (*time.Time, bool)` + +GetLastUsedAtOk returns a tuple with the LastUsedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastUsedAt + +`func (o *ModelsAPIKey) SetLastUsedAt(v time.Time)` + +SetLastUsedAt sets LastUsedAt field to given value. + +### HasLastUsedAt + +`func (o *ModelsAPIKey) HasLastUsedAt() bool` + +HasLastUsedAt returns a boolean if a field has been set. + +### GetName + +`func (o *ModelsAPIKey) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *ModelsAPIKey) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *ModelsAPIKey) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *ModelsAPIKey) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetOrgId + +`func (o *ModelsAPIKey) GetOrgId() string` + +GetOrgId returns the OrgId field if non-nil, zero value otherwise. + +### GetOrgIdOk + +`func (o *ModelsAPIKey) GetOrgIdOk() (*string, bool)` + +GetOrgIdOk returns a tuple with the OrgId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOrgId + +`func (o *ModelsAPIKey) SetOrgId(v string)` + +SetOrgId sets OrgId field to given value. + +### HasOrgId + +`func (o *ModelsAPIKey) HasOrgId() bool` + +HasOrgId returns a boolean if a field has been set. + +### GetPrefix + +`func (o *ModelsAPIKey) GetPrefix() string` + +GetPrefix returns the Prefix field if non-nil, zero value otherwise. + +### GetPrefixOk + +`func (o *ModelsAPIKey) GetPrefixOk() (*string, bool)` + +GetPrefixOk returns a tuple with the Prefix field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPrefix + +`func (o *ModelsAPIKey) SetPrefix(v string)` + +SetPrefix sets Prefix field to given value. + +### HasPrefix + +`func (o *ModelsAPIKey) HasPrefix() bool` + +HasPrefix returns a boolean if a field has been set. + +### GetRevoked + +`func (o *ModelsAPIKey) GetRevoked() bool` + +GetRevoked returns the Revoked field if non-nil, zero value otherwise. + +### GetRevokedOk + +`func (o *ModelsAPIKey) GetRevokedOk() (*bool, bool)` + +GetRevokedOk returns a tuple with the Revoked field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRevoked + +`func (o *ModelsAPIKey) SetRevoked(v bool)` + +SetRevoked sets Revoked field to given value. + +### HasRevoked + +`func (o *ModelsAPIKey) HasRevoked() bool` + +HasRevoked returns a boolean if a field has been set. + +### GetScope + +`func (o *ModelsAPIKey) GetScope() string` + +GetScope returns the Scope field if non-nil, zero value otherwise. + +### GetScopeOk + +`func (o *ModelsAPIKey) GetScopeOk() (*string, bool)` + +GetScopeOk returns a tuple with the Scope field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetScope + +`func (o *ModelsAPIKey) SetScope(v string)` + +SetScope sets Scope field to given value. + +### HasScope + +`func (o *ModelsAPIKey) HasScope() bool` + +HasScope returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *ModelsAPIKey) GetUpdatedAt() time.Time` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *ModelsAPIKey) GetUpdatedAtOk() (*time.Time, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *ModelsAPIKey) SetUpdatedAt(v time.Time)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *ModelsAPIKey) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + +### GetUserId + +`func (o *ModelsAPIKey) GetUserId() string` + +GetUserId returns the UserId field if non-nil, zero value otherwise. + +### GetUserIdOk + +`func (o *ModelsAPIKey) GetUserIdOk() (*string, bool)` + +GetUserIdOk returns a tuple with the UserId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUserId + +`func (o *ModelsAPIKey) SetUserId(v string)` + +SetUserId sets UserId field to given value. + +### HasUserId + +`func (o *ModelsAPIKey) HasUserId() bool` + +HasUserId returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/ModelsOrganization.md b/sdk/go/docs/ModelsOrganization.md new file mode 100644 index 0000000..02fc367 --- /dev/null +++ b/sdk/go/docs/ModelsOrganization.md @@ -0,0 +1,160 @@ +# ModelsOrganization + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CreatedAt** | Pointer to **time.Time** | | [optional] +**Domain** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 | [optional] +**Name** | Pointer to **string** | | [optional] +**UpdatedAt** | Pointer to **time.Time** | | [optional] + +## Methods + +### NewModelsOrganization + +`func NewModelsOrganization() *ModelsOrganization` + +NewModelsOrganization instantiates a new ModelsOrganization object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewModelsOrganizationWithDefaults + +`func NewModelsOrganizationWithDefaults() *ModelsOrganization` + +NewModelsOrganizationWithDefaults instantiates a new ModelsOrganization object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCreatedAt + +`func (o *ModelsOrganization) GetCreatedAt() time.Time` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *ModelsOrganization) GetCreatedAtOk() (*time.Time, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *ModelsOrganization) SetCreatedAt(v time.Time)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *ModelsOrganization) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetDomain + +`func (o *ModelsOrganization) GetDomain() string` + +GetDomain returns the Domain field if non-nil, zero value otherwise. + +### GetDomainOk + +`func (o *ModelsOrganization) GetDomainOk() (*string, bool)` + +GetDomainOk returns a tuple with the Domain field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDomain + +`func (o *ModelsOrganization) SetDomain(v string)` + +SetDomain sets Domain field to given value. + +### HasDomain + +`func (o *ModelsOrganization) HasDomain() bool` + +HasDomain returns a boolean if a field has been set. + +### GetId + +`func (o *ModelsOrganization) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *ModelsOrganization) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *ModelsOrganization) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *ModelsOrganization) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetName + +`func (o *ModelsOrganization) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *ModelsOrganization) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *ModelsOrganization) SetName(v string)` + +SetName sets Name field to given value. + +### HasName + +`func (o *ModelsOrganization) HasName() bool` + +HasName returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *ModelsOrganization) GetUpdatedAt() time.Time` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *ModelsOrganization) GetUpdatedAtOk() (*time.Time, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *ModelsOrganization) SetUpdatedAt(v time.Time)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *ModelsOrganization) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/ModelsUser.md b/sdk/go/docs/ModelsUser.md new file mode 100644 index 0000000..d74bb67 --- /dev/null +++ b/sdk/go/docs/ModelsUser.md @@ -0,0 +1,212 @@ +# ModelsUser + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AvatarUrl** | Pointer to **string** | | [optional] +**CreatedAt** | Pointer to **time.Time** | | [optional] +**DisplayName** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 | [optional] +**IsDisabled** | Pointer to **bool** | | [optional] +**PrimaryEmail** | Pointer to **string** | | [optional] +**UpdatedAt** | Pointer to **time.Time** | | [optional] + +## Methods + +### NewModelsUser + +`func NewModelsUser() *ModelsUser` + +NewModelsUser instantiates a new ModelsUser object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewModelsUserWithDefaults + +`func NewModelsUserWithDefaults() *ModelsUser` + +NewModelsUserWithDefaults instantiates a new ModelsUser object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetAvatarUrl + +`func (o *ModelsUser) GetAvatarUrl() string` + +GetAvatarUrl returns the AvatarUrl field if non-nil, zero value otherwise. + +### GetAvatarUrlOk + +`func (o *ModelsUser) GetAvatarUrlOk() (*string, bool)` + +GetAvatarUrlOk returns a tuple with the AvatarUrl field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAvatarUrl + +`func (o *ModelsUser) SetAvatarUrl(v string)` + +SetAvatarUrl sets AvatarUrl field to given value. + +### HasAvatarUrl + +`func (o *ModelsUser) HasAvatarUrl() bool` + +HasAvatarUrl returns a boolean if a field has been set. + +### GetCreatedAt + +`func (o *ModelsUser) GetCreatedAt() time.Time` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *ModelsUser) GetCreatedAtOk() (*time.Time, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *ModelsUser) SetCreatedAt(v time.Time)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *ModelsUser) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetDisplayName + +`func (o *ModelsUser) GetDisplayName() string` + +GetDisplayName returns the DisplayName field if non-nil, zero value otherwise. + +### GetDisplayNameOk + +`func (o *ModelsUser) GetDisplayNameOk() (*string, bool)` + +GetDisplayNameOk returns a tuple with the DisplayName field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDisplayName + +`func (o *ModelsUser) SetDisplayName(v string)` + +SetDisplayName sets DisplayName field to given value. + +### HasDisplayName + +`func (o *ModelsUser) HasDisplayName() bool` + +HasDisplayName returns a boolean if a field has been set. + +### GetId + +`func (o *ModelsUser) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *ModelsUser) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *ModelsUser) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *ModelsUser) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetIsDisabled + +`func (o *ModelsUser) GetIsDisabled() bool` + +GetIsDisabled returns the IsDisabled field if non-nil, zero value otherwise. + +### GetIsDisabledOk + +`func (o *ModelsUser) GetIsDisabledOk() (*bool, bool)` + +GetIsDisabledOk returns a tuple with the IsDisabled field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetIsDisabled + +`func (o *ModelsUser) SetIsDisabled(v bool)` + +SetIsDisabled sets IsDisabled field to given value. + +### HasIsDisabled + +`func (o *ModelsUser) HasIsDisabled() bool` + +HasIsDisabled returns a boolean if a field has been set. + +### GetPrimaryEmail + +`func (o *ModelsUser) GetPrimaryEmail() string` + +GetPrimaryEmail returns the PrimaryEmail field if non-nil, zero value otherwise. + +### GetPrimaryEmailOk + +`func (o *ModelsUser) GetPrimaryEmailOk() (*string, bool)` + +GetPrimaryEmailOk returns a tuple with the PrimaryEmail field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPrimaryEmail + +`func (o *ModelsUser) SetPrimaryEmail(v string)` + +SetPrimaryEmail sets PrimaryEmail field to given value. + +### HasPrimaryEmail + +`func (o *ModelsUser) HasPrimaryEmail() bool` + +HasPrimaryEmail returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *ModelsUser) GetUpdatedAt() time.Time` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *ModelsUser) GetUpdatedAtOk() (*time.Time, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *ModelsUser) SetUpdatedAt(v time.Time)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *ModelsUser) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/ModelsUserEmail.md b/sdk/go/docs/ModelsUserEmail.md new file mode 100644 index 0000000..ab10365 --- /dev/null +++ b/sdk/go/docs/ModelsUserEmail.md @@ -0,0 +1,238 @@ +# ModelsUserEmail + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CreatedAt** | Pointer to **time.Time** | | [optional] +**Email** | Pointer to **string** | | [optional] +**Id** | Pointer to **string** | example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 | [optional] +**IsPrimary** | Pointer to **bool** | | [optional] +**IsVerified** | Pointer to **bool** | | [optional] +**UpdatedAt** | Pointer to **time.Time** | | [optional] +**User** | Pointer to [**ModelsUser**](ModelsUser.md) | | [optional] +**UserId** | Pointer to **string** | | [optional] + +## Methods + +### NewModelsUserEmail + +`func NewModelsUserEmail() *ModelsUserEmail` + +NewModelsUserEmail instantiates a new ModelsUserEmail object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewModelsUserEmailWithDefaults + +`func NewModelsUserEmailWithDefaults() *ModelsUserEmail` + +NewModelsUserEmailWithDefaults instantiates a new ModelsUserEmail object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCreatedAt + +`func (o *ModelsUserEmail) GetCreatedAt() time.Time` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *ModelsUserEmail) GetCreatedAtOk() (*time.Time, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *ModelsUserEmail) SetCreatedAt(v time.Time)` + +SetCreatedAt sets CreatedAt field to given value. + +### HasCreatedAt + +`func (o *ModelsUserEmail) HasCreatedAt() bool` + +HasCreatedAt returns a boolean if a field has been set. + +### GetEmail + +`func (o *ModelsUserEmail) GetEmail() string` + +GetEmail returns the Email field if non-nil, zero value otherwise. + +### GetEmailOk + +`func (o *ModelsUserEmail) GetEmailOk() (*string, bool)` + +GetEmailOk returns a tuple with the Email field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEmail + +`func (o *ModelsUserEmail) SetEmail(v string)` + +SetEmail sets Email field to given value. + +### HasEmail + +`func (o *ModelsUserEmail) HasEmail() bool` + +HasEmail returns a boolean if a field has been set. + +### GetId + +`func (o *ModelsUserEmail) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *ModelsUserEmail) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *ModelsUserEmail) SetId(v string)` + +SetId sets Id field to given value. + +### HasId + +`func (o *ModelsUserEmail) HasId() bool` + +HasId returns a boolean if a field has been set. + +### GetIsPrimary + +`func (o *ModelsUserEmail) GetIsPrimary() bool` + +GetIsPrimary returns the IsPrimary field if non-nil, zero value otherwise. + +### GetIsPrimaryOk + +`func (o *ModelsUserEmail) GetIsPrimaryOk() (*bool, bool)` + +GetIsPrimaryOk returns a tuple with the IsPrimary field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetIsPrimary + +`func (o *ModelsUserEmail) SetIsPrimary(v bool)` + +SetIsPrimary sets IsPrimary field to given value. + +### HasIsPrimary + +`func (o *ModelsUserEmail) HasIsPrimary() bool` + +HasIsPrimary returns a boolean if a field has been set. + +### GetIsVerified + +`func (o *ModelsUserEmail) GetIsVerified() bool` + +GetIsVerified returns the IsVerified field if non-nil, zero value otherwise. + +### GetIsVerifiedOk + +`func (o *ModelsUserEmail) GetIsVerifiedOk() (*bool, bool)` + +GetIsVerifiedOk returns a tuple with the IsVerified field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetIsVerified + +`func (o *ModelsUserEmail) SetIsVerified(v bool)` + +SetIsVerified sets IsVerified field to given value. + +### HasIsVerified + +`func (o *ModelsUserEmail) HasIsVerified() bool` + +HasIsVerified returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *ModelsUserEmail) GetUpdatedAt() time.Time` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *ModelsUserEmail) GetUpdatedAtOk() (*time.Time, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *ModelsUserEmail) SetUpdatedAt(v time.Time)` + +SetUpdatedAt sets UpdatedAt field to given value. + +### HasUpdatedAt + +`func (o *ModelsUserEmail) HasUpdatedAt() bool` + +HasUpdatedAt returns a boolean if a field has been set. + +### GetUser + +`func (o *ModelsUserEmail) GetUser() ModelsUser` + +GetUser returns the User field if non-nil, zero value otherwise. + +### GetUserOk + +`func (o *ModelsUserEmail) GetUserOk() (*ModelsUser, bool)` + +GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUser + +`func (o *ModelsUserEmail) SetUser(v ModelsUser)` + +SetUser sets User field to given value. + +### HasUser + +`func (o *ModelsUserEmail) HasUser() bool` + +HasUser returns a boolean if a field has been set. + +### GetUserId + +`func (o *ModelsUserEmail) GetUserId() string` + +GetUserId returns the UserId field if non-nil, zero value otherwise. + +### GetUserIdOk + +`func (o *ModelsUserEmail) GetUserIdOk() (*string, bool)` + +GetUserIdOk returns a tuple with the UserId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUserId + +`func (o *ModelsUserEmail) SetUserId(v string)` + +SetUserId sets UserId field to given value. + +### HasUserId + +`func (o *ModelsUserEmail) HasUserId() bool` + +HasUserId returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/docs/OrgsAPI.md b/sdk/go/docs/OrgsAPI.md new file mode 100644 index 0000000..c411a4c --- /dev/null +++ b/sdk/go/docs/OrgsAPI.md @@ -0,0 +1,760 @@ +# \OrgsAPI + +All URIs are relative to *http://localhost:8080/api/v1* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**AddOrUpdateMember**](OrgsAPI.md#AddOrUpdateMember) | **Post** /orgs/{id}/members | Add or update a member (owner/admin) +[**CreateOrg**](OrgsAPI.md#CreateOrg) | **Post** /orgs | Create organization +[**CreateOrgKey**](OrgsAPI.md#CreateOrgKey) | **Post** /orgs/{id}/api-keys | Create org key/secret pair (owner/admin) +[**DeleteOrg**](OrgsAPI.md#DeleteOrg) | **Delete** /orgs/{id} | Delete organization (owner) +[**DeleteOrgKey**](OrgsAPI.md#DeleteOrgKey) | **Delete** /orgs/{id}/api-keys/{key_id} | Delete org key (owner/admin) +[**GetOrg**](OrgsAPI.md#GetOrg) | **Get** /orgs/{id} | Get organization +[**ListMembers**](OrgsAPI.md#ListMembers) | **Get** /orgs/{id}/members | List members in org +[**ListMyOrgs**](OrgsAPI.md#ListMyOrgs) | **Get** /orgs | List organizations I belong to +[**ListOrgKeys**](OrgsAPI.md#ListOrgKeys) | **Get** /orgs/{id}/api-keys | List org-scoped API keys (no secrets) +[**RemoveMember**](OrgsAPI.md#RemoveMember) | **Delete** /orgs/{id}/members/{user_id} | Remove a member (owner/admin) +[**UpdateOrg**](OrgsAPI.md#UpdateOrg) | **Patch** /orgs/{id} | Update organization (owner/admin) + + + +## AddOrUpdateMember + +> HandlersMemberOut AddOrUpdateMember(ctx, id).Body(body).Execute() + +Add or update a member (owner/admin) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + body := *openapiclient.NewHandlersMemberUpsertReq() // HandlersMemberUpsertReq | User & role + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.OrgsAPI.AddOrUpdateMember(context.Background(), id).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.AddOrUpdateMember``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `AddOrUpdateMember`: HandlersMemberOut + fmt.Fprintf(os.Stdout, "Response from `OrgsAPI.AddOrUpdateMember`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiAddOrUpdateMemberRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **body** | [**HandlersMemberUpsertReq**](HandlersMemberUpsertReq.md) | User & role | + +### Return type + +[**HandlersMemberOut**](HandlersMemberOut.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## CreateOrg + +> ModelsOrganization CreateOrg(ctx).Body(body).Execute() + +Create organization + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + body := *openapiclient.NewHandlersOrgCreateReq() // HandlersOrgCreateReq | Org payload + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.OrgsAPI.CreateOrg(context.Background()).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.CreateOrg``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `CreateOrg`: ModelsOrganization + fmt.Fprintf(os.Stdout, "Response from `OrgsAPI.CreateOrg`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiCreateOrgRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**HandlersOrgCreateReq**](HandlersOrgCreateReq.md) | Org payload | + +### Return type + +[**ModelsOrganization**](ModelsOrganization.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## CreateOrgKey + +> HandlersOrgKeyCreateResp CreateOrgKey(ctx, id).Body(body).Execute() + +Create org key/secret pair (owner/admin) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + body := *openapiclient.NewHandlersOrgKeyCreateReq() // HandlersOrgKeyCreateReq | Key name + optional expiry + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.OrgsAPI.CreateOrgKey(context.Background(), id).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.CreateOrgKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `CreateOrgKey`: HandlersOrgKeyCreateResp + fmt.Fprintf(os.Stdout, "Response from `OrgsAPI.CreateOrgKey`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiCreateOrgKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **body** | [**HandlersOrgKeyCreateReq**](HandlersOrgKeyCreateReq.md) | Key name + optional expiry | + +### Return type + +[**HandlersOrgKeyCreateResp**](HandlersOrgKeyCreateResp.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## DeleteOrg + +> DeleteOrg(ctx, id).Execute() + +Delete organization (owner) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.OrgsAPI.DeleteOrg(context.Background(), id).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.DeleteOrg``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiDeleteOrgRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## DeleteOrgKey + +> DeleteOrgKey(ctx, id, keyId).Execute() + +Delete org key (owner/admin) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + keyId := "keyId_example" // string | Key ID (UUID) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.OrgsAPI.DeleteOrgKey(context.Background(), id, keyId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.DeleteOrgKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | +**keyId** | **string** | Key ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiDeleteOrgKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + +### Return type + + (empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## GetOrg + +> ModelsOrganization GetOrg(ctx, id).Execute() + +Get organization + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.OrgsAPI.GetOrg(context.Background(), id).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.GetOrg``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetOrg`: ModelsOrganization + fmt.Fprintf(os.Stdout, "Response from `OrgsAPI.GetOrg`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetOrgRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + +[**ModelsOrganization**](ModelsOrganization.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListMembers + +> []HandlersMemberOut ListMembers(ctx, id).Execute() + +List members in org + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.OrgsAPI.ListMembers(context.Background(), id).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.ListMembers``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListMembers`: []HandlersMemberOut + fmt.Fprintf(os.Stdout, "Response from `OrgsAPI.ListMembers`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiListMembersRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + +[**[]HandlersMemberOut**](HandlersMemberOut.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListMyOrgs + +> []ModelsOrganization ListMyOrgs(ctx).Execute() + +List organizations I belong to + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.OrgsAPI.ListMyOrgs(context.Background()).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.ListMyOrgs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListMyOrgs`: []ModelsOrganization + fmt.Fprintf(os.Stdout, "Response from `OrgsAPI.ListMyOrgs`: %v\n", resp) +} +``` + +### Path Parameters + +This endpoint does not need any parameter. + +### Other Parameters + +Other parameters are passed through a pointer to a apiListMyOrgsRequest struct via the builder pattern + + +### Return type + +[**[]ModelsOrganization**](ModelsOrganization.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListOrgKeys + +> []ModelsAPIKey ListOrgKeys(ctx, id).Execute() + +List org-scoped API keys (no secrets) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.OrgsAPI.ListOrgKeys(context.Background(), id).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.ListOrgKeys``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListOrgKeys`: []ModelsAPIKey + fmt.Fprintf(os.Stdout, "Response from `OrgsAPI.ListOrgKeys`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiListOrgKeysRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + +[**[]ModelsAPIKey**](ModelsAPIKey.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## RemoveMember + +> RemoveMember(ctx, id, userId).Execute() + +Remove a member (owner/admin) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + userId := "userId_example" // string | User ID (UUID) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.OrgsAPI.RemoveMember(context.Background(), id, userId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.RemoveMember``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | +**userId** | **string** | User ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiRemoveMemberRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + +### Return type + + (empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## UpdateOrg + +> ModelsOrganization UpdateOrg(ctx, id).Body(body).Execute() + +Update organization (owner/admin) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Org ID (UUID) + body := *openapiclient.NewHandlersOrgUpdateReq() // HandlersOrgUpdateReq | Update payload + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.OrgsAPI.UpdateOrg(context.Background(), id).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OrgsAPI.UpdateOrg``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `UpdateOrg`: ModelsOrganization + fmt.Fprintf(os.Stdout, "Response from `OrgsAPI.UpdateOrg`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Org ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiUpdateOrgRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **body** | [**HandlersOrgUpdateReq**](HandlersOrgUpdateReq.md) | Update payload | + +### Return type + +[**ModelsOrganization**](ModelsOrganization.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/sdk/go/docs/ServersAPI.md b/sdk/go/docs/ServersAPI.md new file mode 100644 index 0000000..2613151 --- /dev/null +++ b/sdk/go/docs/ServersAPI.md @@ -0,0 +1,369 @@ +# \ServersAPI + +All URIs are relative to *http://localhost:8080/api/v1* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**CreateServer**](ServersAPI.md#CreateServer) | **Post** /servers | Create server (org scoped) +[**DeleteServer**](ServersAPI.md#DeleteServer) | **Delete** /servers/{id} | Delete server (org scoped) +[**GetServer**](ServersAPI.md#GetServer) | **Get** /servers/{id} | Get server by ID (org scoped) +[**ListServers**](ServersAPI.md#ListServers) | **Get** /servers | List servers (org scoped) +[**UpdateServer**](ServersAPI.md#UpdateServer) | **Patch** /servers/{id} | Update server (org scoped) + + + +## CreateServer + +> DtoServerResponse CreateServer(ctx).Body(body).XOrgID(xOrgID).Execute() + +Create server (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + body := *openapiclient.NewDtoCreateServerRequest() // DtoCreateServerRequest | Server payload + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.ServersAPI.CreateServer(context.Background()).Body(body).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `ServersAPI.CreateServer``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `CreateServer`: DtoServerResponse + fmt.Fprintf(os.Stdout, "Response from `ServersAPI.CreateServer`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiCreateServerRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**DtoCreateServerRequest**](DtoCreateServerRequest.md) | Server payload | + **xOrgID** | **string** | Organization UUID | + +### Return type + +[**DtoServerResponse**](DtoServerResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## DeleteServer + +> string DeleteServer(ctx, id).XOrgID(xOrgID).Execute() + +Delete server (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Server ID (UUID) + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.ServersAPI.DeleteServer(context.Background(), id).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `ServersAPI.DeleteServer``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `DeleteServer`: string + fmt.Fprintf(os.Stdout, "Response from `ServersAPI.DeleteServer`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Server ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiDeleteServerRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **xOrgID** | **string** | Organization UUID | + +### Return type + +**string** + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## GetServer + +> DtoServerResponse GetServer(ctx, id).XOrgID(xOrgID).Execute() + +Get server by ID (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Server ID (UUID) + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.ServersAPI.GetServer(context.Background(), id).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `ServersAPI.GetServer``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetServer`: DtoServerResponse + fmt.Fprintf(os.Stdout, "Response from `ServersAPI.GetServer`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Server ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetServerRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **xOrgID** | **string** | Organization UUID | + +### Return type + +[**DtoServerResponse**](DtoServerResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListServers + +> []DtoServerResponse ListServers(ctx).XOrgID(xOrgID).Status(status).Role(role).Execute() + +List servers (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + status := "status_example" // string | Filter by status (pending|provisioning|ready|failed) (optional) + role := "role_example" // string | Filter by role (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.ServersAPI.ListServers(context.Background()).XOrgID(xOrgID).Status(status).Role(role).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `ServersAPI.ListServers``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListServers`: []DtoServerResponse + fmt.Fprintf(os.Stdout, "Response from `ServersAPI.ListServers`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiListServersRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **xOrgID** | **string** | Organization UUID | + **status** | **string** | Filter by status (pending|provisioning|ready|failed) | + **role** | **string** | Filter by role | + +### Return type + +[**[]DtoServerResponse**](DtoServerResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## UpdateServer + +> DtoServerResponse UpdateServer(ctx, id).Body(body).XOrgID(xOrgID).Execute() + +Update server (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Server ID (UUID) + body := *openapiclient.NewDtoUpdateServerRequest() // DtoUpdateServerRequest | Fields to update + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.ServersAPI.UpdateServer(context.Background(), id).Body(body).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `ServersAPI.UpdateServer``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `UpdateServer`: DtoServerResponse + fmt.Fprintf(os.Stdout, "Response from `ServersAPI.UpdateServer`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Server ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiUpdateServerRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **body** | [**DtoUpdateServerRequest**](DtoUpdateServerRequest.md) | Fields to update | + **xOrgID** | **string** | Organization UUID | + +### Return type + +[**DtoServerResponse**](DtoServerResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/sdk/go/docs/SshAPI.md b/sdk/go/docs/SshAPI.md new file mode 100644 index 0000000..0125ea0 --- /dev/null +++ b/sdk/go/docs/SshAPI.md @@ -0,0 +1,367 @@ +# \SshAPI + +All URIs are relative to *http://localhost:8080/api/v1* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**CreateSSHKey**](SshAPI.md#CreateSSHKey) | **Post** /ssh | Create ssh keypair (org scoped) +[**DeleteSSHKey**](SshAPI.md#DeleteSSHKey) | **Delete** /ssh/{id} | Delete ssh keypair (org scoped) +[**DownloadSSHKey**](SshAPI.md#DownloadSSHKey) | **Get** /ssh/{id}/download | Download ssh key files by ID (org scoped) +[**GetSSHKey**](SshAPI.md#GetSSHKey) | **Get** /ssh/{id} | Get ssh key by ID (org scoped) +[**ListPublicSshKeys**](SshAPI.md#ListPublicSshKeys) | **Get** /ssh | List ssh keys (org scoped) + + + +## CreateSSHKey + +> DtoSshResponse CreateSSHKey(ctx).Body(body).XOrgID(xOrgID).Execute() + +Create ssh keypair (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + body := *openapiclient.NewDtoCreateSSHRequest() // DtoCreateSSHRequest | Key generation options + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.SshAPI.CreateSSHKey(context.Background()).Body(body).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `SshAPI.CreateSSHKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `CreateSSHKey`: DtoSshResponse + fmt.Fprintf(os.Stdout, "Response from `SshAPI.CreateSSHKey`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiCreateSSHKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**DtoCreateSSHRequest**](DtoCreateSSHRequest.md) | Key generation options | + **xOrgID** | **string** | Organization UUID | + +### Return type + +[**DtoSshResponse**](DtoSshResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## DeleteSSHKey + +> string DeleteSSHKey(ctx, id).XOrgID(xOrgID).Execute() + +Delete ssh keypair (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | SSH Key ID (UUID) + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.SshAPI.DeleteSSHKey(context.Background(), id).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `SshAPI.DeleteSSHKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `DeleteSSHKey`: string + fmt.Fprintf(os.Stdout, "Response from `SshAPI.DeleteSSHKey`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | SSH Key ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiDeleteSSHKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **xOrgID** | **string** | Organization UUID | + +### Return type + +**string** + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## DownloadSSHKey + +> string DownloadSSHKey(ctx, id).XOrgID(xOrgID).Part(part).Execute() + +Download ssh key files by ID (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + xOrgID := "xOrgID_example" // string | Organization UUID + id := "id_example" // string | SSH Key ID (UUID) + part := "part_example" // string | Which part to download + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.SshAPI.DownloadSSHKey(context.Background(), id).XOrgID(xOrgID).Part(part).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `SshAPI.DownloadSSHKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `DownloadSSHKey`: string + fmt.Fprintf(os.Stdout, "Response from `SshAPI.DownloadSSHKey`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | SSH Key ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiDownloadSSHKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **xOrgID** | **string** | Organization UUID | + + **part** | **string** | Which part to download | + +### Return type + +**string** + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## GetSSHKey + +> DtoSshRevealResponse GetSSHKey(ctx, id).XOrgID(xOrgID).Reveal(reveal).Execute() + +Get ssh key by ID (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | SSH Key ID (UUID) + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + reveal := true // bool | Reveal private key PEM (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.SshAPI.GetSSHKey(context.Background(), id).XOrgID(xOrgID).Reveal(reveal).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `SshAPI.GetSSHKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetSSHKey`: DtoSshRevealResponse + fmt.Fprintf(os.Stdout, "Response from `SshAPI.GetSSHKey`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | SSH Key ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetSSHKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **xOrgID** | **string** | Organization UUID | + **reveal** | **bool** | Reveal private key PEM | + +### Return type + +[**DtoSshRevealResponse**](DtoSshRevealResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListPublicSshKeys + +> []DtoSshResponse ListPublicSshKeys(ctx).XOrgID(xOrgID).Execute() + +List ssh keys (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.SshAPI.ListPublicSshKeys(context.Background()).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `SshAPI.ListPublicSshKeys``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListPublicSshKeys`: []DtoSshResponse + fmt.Fprintf(os.Stdout, "Response from `SshAPI.ListPublicSshKeys`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiListPublicSshKeysRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **xOrgID** | **string** | Organization UUID | + +### Return type + +[**[]DtoSshResponse**](DtoSshResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/sdk/go/docs/TaintsAPI.md b/sdk/go/docs/TaintsAPI.md new file mode 100644 index 0000000..eecff51 --- /dev/null +++ b/sdk/go/docs/TaintsAPI.md @@ -0,0 +1,369 @@ +# \TaintsAPI + +All URIs are relative to *http://localhost:8080/api/v1* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**CreateTaint**](TaintsAPI.md#CreateTaint) | **Post** /taints | Create node taint (org scoped) +[**DeleteTaint**](TaintsAPI.md#DeleteTaint) | **Delete** /taints/{id} | Delete taint (org scoped) +[**GetTaint**](TaintsAPI.md#GetTaint) | **Get** /taints/{id} | Get node taint by ID (org scoped) +[**ListTaints**](TaintsAPI.md#ListTaints) | **Get** /taints | List node pool taints (org scoped) +[**UpdateTaint**](TaintsAPI.md#UpdateTaint) | **Patch** /taints/{id} | Update node taint (org scoped) + + + +## CreateTaint + +> DtoTaintResponse CreateTaint(ctx).Body(body).XOrgID(xOrgID).Execute() + +Create node taint (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + body := *openapiclient.NewDtoCreateTaintRequest() // DtoCreateTaintRequest | Taint payload + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.TaintsAPI.CreateTaint(context.Background()).Body(body).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TaintsAPI.CreateTaint``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `CreateTaint`: DtoTaintResponse + fmt.Fprintf(os.Stdout, "Response from `TaintsAPI.CreateTaint`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiCreateTaintRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**DtoCreateTaintRequest**](DtoCreateTaintRequest.md) | Taint payload | + **xOrgID** | **string** | Organization UUID | + +### Return type + +[**DtoTaintResponse**](DtoTaintResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## DeleteTaint + +> string DeleteTaint(ctx, id).XOrgID(xOrgID).Execute() + +Delete taint (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Node Taint ID (UUID) + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.TaintsAPI.DeleteTaint(context.Background(), id).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TaintsAPI.DeleteTaint``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `DeleteTaint`: string + fmt.Fprintf(os.Stdout, "Response from `TaintsAPI.DeleteTaint`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Node Taint ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiDeleteTaintRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **xOrgID** | **string** | Organization UUID | + +### Return type + +**string** + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## GetTaint + +> DtoTaintResponse GetTaint(ctx, id).XOrgID(xOrgID).Execute() + +Get node taint by ID (org scoped) + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Node Taint ID (UUID) + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.TaintsAPI.GetTaint(context.Background(), id).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TaintsAPI.GetTaint``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetTaint`: DtoTaintResponse + fmt.Fprintf(os.Stdout, "Response from `TaintsAPI.GetTaint`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Node Taint ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetTaintRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **xOrgID** | **string** | Organization UUID | + +### Return type + +[**DtoTaintResponse**](DtoTaintResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListTaints + +> []DtoTaintResponse ListTaints(ctx).XOrgID(xOrgID).Key(key).Value(value).Q(q).Execute() + +List node pool taints (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + key := "key_example" // string | Exact key (optional) + value := "value_example" // string | Exact value (optional) + q := "q_example" // string | key contains (case-insensitive) (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.TaintsAPI.ListTaints(context.Background()).XOrgID(xOrgID).Key(key).Value(value).Q(q).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TaintsAPI.ListTaints``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListTaints`: []DtoTaintResponse + fmt.Fprintf(os.Stdout, "Response from `TaintsAPI.ListTaints`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiListTaintsRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **xOrgID** | **string** | Organization UUID | + **key** | **string** | Exact key | + **value** | **string** | Exact value | + **q** | **string** | key contains (case-insensitive) | + +### Return type + +[**[]DtoTaintResponse**](DtoTaintResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## UpdateTaint + +> DtoTaintResponse UpdateTaint(ctx, id).Body(body).XOrgID(xOrgID).Execute() + +Update node taint (org scoped) + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/glueops/autoglue-sdk" +) + +func main() { + id := "id_example" // string | Node Taint ID (UUID) + body := *openapiclient.NewDtoUpdateTaintRequest() // DtoUpdateTaintRequest | Fields to update + xOrgID := "xOrgID_example" // string | Organization UUID (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.TaintsAPI.UpdateTaint(context.Background(), id).Body(body).XOrgID(xOrgID).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TaintsAPI.UpdateTaint``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `UpdateTaint`: DtoTaintResponse + fmt.Fprintf(os.Stdout, "Response from `TaintsAPI.UpdateTaint`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | Node Taint ID (UUID) | + +### Other Parameters + +Other parameters are passed through a pointer to a apiUpdateTaintRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **body** | [**DtoUpdateTaintRequest**](DtoUpdateTaintRequest.md) | Fields to update | + **xOrgID** | **string** | Organization UUID | + +### Return type + +[**DtoTaintResponse**](DtoTaintResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/sdk/go/docs/UtilsErrorResponse.md b/sdk/go/docs/UtilsErrorResponse.md new file mode 100644 index 0000000..c639ea8 --- /dev/null +++ b/sdk/go/docs/UtilsErrorResponse.md @@ -0,0 +1,82 @@ +# UtilsErrorResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Code** | Pointer to **string** | A machine-readable error code, e.g. \"validation_error\" example: validation_error | [optional] +**Message** | Pointer to **string** | Human-readable message example: slug is required | [optional] + +## Methods + +### NewUtilsErrorResponse + +`func NewUtilsErrorResponse() *UtilsErrorResponse` + +NewUtilsErrorResponse instantiates a new UtilsErrorResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUtilsErrorResponseWithDefaults + +`func NewUtilsErrorResponseWithDefaults() *UtilsErrorResponse` + +NewUtilsErrorResponseWithDefaults instantiates a new UtilsErrorResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCode + +`func (o *UtilsErrorResponse) GetCode() string` + +GetCode returns the Code field if non-nil, zero value otherwise. + +### GetCodeOk + +`func (o *UtilsErrorResponse) GetCodeOk() (*string, bool)` + +GetCodeOk returns a tuple with the Code field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCode + +`func (o *UtilsErrorResponse) SetCode(v string)` + +SetCode sets Code field to given value. + +### HasCode + +`func (o *UtilsErrorResponse) HasCode() bool` + +HasCode returns a boolean if a field has been set. + +### GetMessage + +`func (o *UtilsErrorResponse) GetMessage() string` + +GetMessage returns the Message field if non-nil, zero value otherwise. + +### GetMessageOk + +`func (o *UtilsErrorResponse) GetMessageOk() (*string, bool)` + +GetMessageOk returns a tuple with the Message field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMessage + +`func (o *UtilsErrorResponse) SetMessage(v string)` + +SetMessage sets Message field to given value. + +### HasMessage + +`func (o *UtilsErrorResponse) HasMessage() bool` + +HasMessage returns a boolean if a field has been set. + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdk/go/git_push.sh b/sdk/go/git_push.sh new file mode 100644 index 0000000..b032ce7 --- /dev/null +++ b/sdk/go/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="glueops" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="autoglue-sdk" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/sdk/go/go.mod b/sdk/go/go.mod new file mode 100644 index 0000000..4b4bcc5 --- /dev/null +++ b/sdk/go/go.mod @@ -0,0 +1,6 @@ +module github.com/glueops/autoglue-sdk + +go 1.23 + +require ( +) diff --git a/sdk/go/go.sum b/sdk/go/go.sum new file mode 100644 index 0000000..c966c8d --- /dev/null +++ b/sdk/go/go.sum @@ -0,0 +1,11 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/sdk/go/model_dto_auth_start_response.go b/sdk/go/model_dto_auth_start_response.go new file mode 100644 index 0000000..4e99012 --- /dev/null +++ b/sdk/go/model_dto_auth_start_response.go @@ -0,0 +1,124 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoAuthStartResponse type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoAuthStartResponse{} + +// DtoAuthStartResponse struct for DtoAuthStartResponse +type DtoAuthStartResponse struct { + AuthUrl *string `json:"auth_url,omitempty"` +} + +// NewDtoAuthStartResponse instantiates a new DtoAuthStartResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoAuthStartResponse() *DtoAuthStartResponse { + this := DtoAuthStartResponse{} + return &this +} + +// NewDtoAuthStartResponseWithDefaults instantiates a new DtoAuthStartResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoAuthStartResponseWithDefaults() *DtoAuthStartResponse { + this := DtoAuthStartResponse{} + return &this +} + +// GetAuthUrl returns the AuthUrl field value if set, zero value otherwise. +func (o *DtoAuthStartResponse) GetAuthUrl() string { + if o == nil || IsNil(o.AuthUrl) { + var ret string + return ret + } + return *o.AuthUrl +} + +// GetAuthUrlOk returns a tuple with the AuthUrl field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoAuthStartResponse) GetAuthUrlOk() (*string, bool) { + if o == nil || IsNil(o.AuthUrl) { + return nil, false + } + return o.AuthUrl, true +} + +// HasAuthUrl returns a boolean if a field has been set. +func (o *DtoAuthStartResponse) HasAuthUrl() bool { + if o != nil && !IsNil(o.AuthUrl) { + return true + } + + return false +} + +// SetAuthUrl gets a reference to the given string and assigns it to the AuthUrl field. +func (o *DtoAuthStartResponse) SetAuthUrl(v string) { + o.AuthUrl = &v +} + +func (o DtoAuthStartResponse) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoAuthStartResponse) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.AuthUrl) { + toSerialize["auth_url"] = o.AuthUrl + } + return toSerialize, nil +} + +type NullableDtoAuthStartResponse struct { + value *DtoAuthStartResponse + isSet bool +} + +func (v NullableDtoAuthStartResponse) Get() *DtoAuthStartResponse { + return v.value +} + +func (v *NullableDtoAuthStartResponse) Set(val *DtoAuthStartResponse) { + v.value = val + v.isSet = true +} + +func (v NullableDtoAuthStartResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoAuthStartResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoAuthStartResponse(val *DtoAuthStartResponse) *NullableDtoAuthStartResponse { + return &NullableDtoAuthStartResponse{value: val, isSet: true} +} + +func (v NullableDtoAuthStartResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoAuthStartResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_create_server_request.go b/sdk/go/model_dto_create_server_request.go new file mode 100644 index 0000000..68d5836 --- /dev/null +++ b/sdk/go/model_dto_create_server_request.go @@ -0,0 +1,340 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoCreateServerRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoCreateServerRequest{} + +// DtoCreateServerRequest struct for DtoCreateServerRequest +type DtoCreateServerRequest struct { + Hostname *string `json:"hostname,omitempty"` + PrivateIpAddress *string `json:"private_ip_address,omitempty"` + PublicIpAddress *string `json:"public_ip_address,omitempty"` + Role *string `json:"role,omitempty"` + SshKeyId *string `json:"ssh_key_id,omitempty"` + SshUser *string `json:"ssh_user,omitempty"` + Status *string `json:"status,omitempty"` +} + +// NewDtoCreateServerRequest instantiates a new DtoCreateServerRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoCreateServerRequest() *DtoCreateServerRequest { + this := DtoCreateServerRequest{} + return &this +} + +// NewDtoCreateServerRequestWithDefaults instantiates a new DtoCreateServerRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoCreateServerRequestWithDefaults() *DtoCreateServerRequest { + this := DtoCreateServerRequest{} + return &this +} + +// GetHostname returns the Hostname field value if set, zero value otherwise. +func (o *DtoCreateServerRequest) GetHostname() string { + if o == nil || IsNil(o.Hostname) { + var ret string + return ret + } + return *o.Hostname +} + +// GetHostnameOk returns a tuple with the Hostname field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateServerRequest) GetHostnameOk() (*string, bool) { + if o == nil || IsNil(o.Hostname) { + return nil, false + } + return o.Hostname, true +} + +// HasHostname returns a boolean if a field has been set. +func (o *DtoCreateServerRequest) HasHostname() bool { + if o != nil && !IsNil(o.Hostname) { + return true + } + + return false +} + +// SetHostname gets a reference to the given string and assigns it to the Hostname field. +func (o *DtoCreateServerRequest) SetHostname(v string) { + o.Hostname = &v +} + +// GetPrivateIpAddress returns the PrivateIpAddress field value if set, zero value otherwise. +func (o *DtoCreateServerRequest) GetPrivateIpAddress() string { + if o == nil || IsNil(o.PrivateIpAddress) { + var ret string + return ret + } + return *o.PrivateIpAddress +} + +// GetPrivateIpAddressOk returns a tuple with the PrivateIpAddress field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateServerRequest) GetPrivateIpAddressOk() (*string, bool) { + if o == nil || IsNil(o.PrivateIpAddress) { + return nil, false + } + return o.PrivateIpAddress, true +} + +// HasPrivateIpAddress returns a boolean if a field has been set. +func (o *DtoCreateServerRequest) HasPrivateIpAddress() bool { + if o != nil && !IsNil(o.PrivateIpAddress) { + return true + } + + return false +} + +// SetPrivateIpAddress gets a reference to the given string and assigns it to the PrivateIpAddress field. +func (o *DtoCreateServerRequest) SetPrivateIpAddress(v string) { + o.PrivateIpAddress = &v +} + +// GetPublicIpAddress returns the PublicIpAddress field value if set, zero value otherwise. +func (o *DtoCreateServerRequest) GetPublicIpAddress() string { + if o == nil || IsNil(o.PublicIpAddress) { + var ret string + return ret + } + return *o.PublicIpAddress +} + +// GetPublicIpAddressOk returns a tuple with the PublicIpAddress field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateServerRequest) GetPublicIpAddressOk() (*string, bool) { + if o == nil || IsNil(o.PublicIpAddress) { + return nil, false + } + return o.PublicIpAddress, true +} + +// HasPublicIpAddress returns a boolean if a field has been set. +func (o *DtoCreateServerRequest) HasPublicIpAddress() bool { + if o != nil && !IsNil(o.PublicIpAddress) { + return true + } + + return false +} + +// SetPublicIpAddress gets a reference to the given string and assigns it to the PublicIpAddress field. +func (o *DtoCreateServerRequest) SetPublicIpAddress(v string) { + o.PublicIpAddress = &v +} + +// GetRole returns the Role field value if set, zero value otherwise. +func (o *DtoCreateServerRequest) GetRole() string { + if o == nil || IsNil(o.Role) { + var ret string + return ret + } + return *o.Role +} + +// GetRoleOk returns a tuple with the Role field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateServerRequest) GetRoleOk() (*string, bool) { + if o == nil || IsNil(o.Role) { + return nil, false + } + return o.Role, true +} + +// HasRole returns a boolean if a field has been set. +func (o *DtoCreateServerRequest) HasRole() bool { + if o != nil && !IsNil(o.Role) { + return true + } + + return false +} + +// SetRole gets a reference to the given string and assigns it to the Role field. +func (o *DtoCreateServerRequest) SetRole(v string) { + o.Role = &v +} + +// GetSshKeyId returns the SshKeyId field value if set, zero value otherwise. +func (o *DtoCreateServerRequest) GetSshKeyId() string { + if o == nil || IsNil(o.SshKeyId) { + var ret string + return ret + } + return *o.SshKeyId +} + +// GetSshKeyIdOk returns a tuple with the SshKeyId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateServerRequest) GetSshKeyIdOk() (*string, bool) { + if o == nil || IsNil(o.SshKeyId) { + return nil, false + } + return o.SshKeyId, true +} + +// HasSshKeyId returns a boolean if a field has been set. +func (o *DtoCreateServerRequest) HasSshKeyId() bool { + if o != nil && !IsNil(o.SshKeyId) { + return true + } + + return false +} + +// SetSshKeyId gets a reference to the given string and assigns it to the SshKeyId field. +func (o *DtoCreateServerRequest) SetSshKeyId(v string) { + o.SshKeyId = &v +} + +// GetSshUser returns the SshUser field value if set, zero value otherwise. +func (o *DtoCreateServerRequest) GetSshUser() string { + if o == nil || IsNil(o.SshUser) { + var ret string + return ret + } + return *o.SshUser +} + +// GetSshUserOk returns a tuple with the SshUser field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateServerRequest) GetSshUserOk() (*string, bool) { + if o == nil || IsNil(o.SshUser) { + return nil, false + } + return o.SshUser, true +} + +// HasSshUser returns a boolean if a field has been set. +func (o *DtoCreateServerRequest) HasSshUser() bool { + if o != nil && !IsNil(o.SshUser) { + return true + } + + return false +} + +// SetSshUser gets a reference to the given string and assigns it to the SshUser field. +func (o *DtoCreateServerRequest) SetSshUser(v string) { + o.SshUser = &v +} + +// GetStatus returns the Status field value if set, zero value otherwise. +func (o *DtoCreateServerRequest) GetStatus() string { + if o == nil || IsNil(o.Status) { + var ret string + return ret + } + return *o.Status +} + +// GetStatusOk returns a tuple with the Status field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateServerRequest) GetStatusOk() (*string, bool) { + if o == nil || IsNil(o.Status) { + return nil, false + } + return o.Status, true +} + +// HasStatus returns a boolean if a field has been set. +func (o *DtoCreateServerRequest) HasStatus() bool { + if o != nil && !IsNil(o.Status) { + return true + } + + return false +} + +// SetStatus gets a reference to the given string and assigns it to the Status field. +func (o *DtoCreateServerRequest) SetStatus(v string) { + o.Status = &v +} + +func (o DtoCreateServerRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoCreateServerRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Hostname) { + toSerialize["hostname"] = o.Hostname + } + if !IsNil(o.PrivateIpAddress) { + toSerialize["private_ip_address"] = o.PrivateIpAddress + } + if !IsNil(o.PublicIpAddress) { + toSerialize["public_ip_address"] = o.PublicIpAddress + } + if !IsNil(o.Role) { + toSerialize["role"] = o.Role + } + if !IsNil(o.SshKeyId) { + toSerialize["ssh_key_id"] = o.SshKeyId + } + if !IsNil(o.SshUser) { + toSerialize["ssh_user"] = o.SshUser + } + if !IsNil(o.Status) { + toSerialize["status"] = o.Status + } + return toSerialize, nil +} + +type NullableDtoCreateServerRequest struct { + value *DtoCreateServerRequest + isSet bool +} + +func (v NullableDtoCreateServerRequest) Get() *DtoCreateServerRequest { + return v.value +} + +func (v *NullableDtoCreateServerRequest) Set(val *DtoCreateServerRequest) { + v.value = val + v.isSet = true +} + +func (v NullableDtoCreateServerRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoCreateServerRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoCreateServerRequest(val *DtoCreateServerRequest) *NullableDtoCreateServerRequest { + return &NullableDtoCreateServerRequest{value: val, isSet: true} +} + +func (v NullableDtoCreateServerRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoCreateServerRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_create_ssh_request.go b/sdk/go/model_dto_create_ssh_request.go new file mode 100644 index 0000000..7ec89ed --- /dev/null +++ b/sdk/go/model_dto_create_ssh_request.go @@ -0,0 +1,234 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoCreateSSHRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoCreateSSHRequest{} + +// DtoCreateSSHRequest struct for DtoCreateSSHRequest +type DtoCreateSSHRequest struct { + // Only for RSA + Bits *int32 `json:"bits,omitempty"` + Comment *string `json:"comment,omitempty"` + Name *string `json:"name,omitempty"` + // \"rsa\" (default) or \"ed25519\" + Type *string `json:"type,omitempty"` +} + +// NewDtoCreateSSHRequest instantiates a new DtoCreateSSHRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoCreateSSHRequest() *DtoCreateSSHRequest { + this := DtoCreateSSHRequest{} + return &this +} + +// NewDtoCreateSSHRequestWithDefaults instantiates a new DtoCreateSSHRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoCreateSSHRequestWithDefaults() *DtoCreateSSHRequest { + this := DtoCreateSSHRequest{} + return &this +} + +// GetBits returns the Bits field value if set, zero value otherwise. +func (o *DtoCreateSSHRequest) GetBits() int32 { + if o == nil || IsNil(o.Bits) { + var ret int32 + return ret + } + return *o.Bits +} + +// GetBitsOk returns a tuple with the Bits field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateSSHRequest) GetBitsOk() (*int32, bool) { + if o == nil || IsNil(o.Bits) { + return nil, false + } + return o.Bits, true +} + +// HasBits returns a boolean if a field has been set. +func (o *DtoCreateSSHRequest) HasBits() bool { + if o != nil && !IsNil(o.Bits) { + return true + } + + return false +} + +// SetBits gets a reference to the given int32 and assigns it to the Bits field. +func (o *DtoCreateSSHRequest) SetBits(v int32) { + o.Bits = &v +} + +// GetComment returns the Comment field value if set, zero value otherwise. +func (o *DtoCreateSSHRequest) GetComment() string { + if o == nil || IsNil(o.Comment) { + var ret string + return ret + } + return *o.Comment +} + +// GetCommentOk returns a tuple with the Comment field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateSSHRequest) GetCommentOk() (*string, bool) { + if o == nil || IsNil(o.Comment) { + return nil, false + } + return o.Comment, true +} + +// HasComment returns a boolean if a field has been set. +func (o *DtoCreateSSHRequest) HasComment() bool { + if o != nil && !IsNil(o.Comment) { + return true + } + + return false +} + +// SetComment gets a reference to the given string and assigns it to the Comment field. +func (o *DtoCreateSSHRequest) SetComment(v string) { + o.Comment = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *DtoCreateSSHRequest) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateSSHRequest) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *DtoCreateSSHRequest) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *DtoCreateSSHRequest) SetName(v string) { + o.Name = &v +} + +// GetType returns the Type field value if set, zero value otherwise. +func (o *DtoCreateSSHRequest) GetType() string { + if o == nil || IsNil(o.Type) { + var ret string + return ret + } + return *o.Type +} + +// GetTypeOk returns a tuple with the Type field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateSSHRequest) GetTypeOk() (*string, bool) { + if o == nil || IsNil(o.Type) { + return nil, false + } + return o.Type, true +} + +// HasType returns a boolean if a field has been set. +func (o *DtoCreateSSHRequest) HasType() bool { + if o != nil && !IsNil(o.Type) { + return true + } + + return false +} + +// SetType gets a reference to the given string and assigns it to the Type field. +func (o *DtoCreateSSHRequest) SetType(v string) { + o.Type = &v +} + +func (o DtoCreateSSHRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoCreateSSHRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Bits) { + toSerialize["bits"] = o.Bits + } + if !IsNil(o.Comment) { + toSerialize["comment"] = o.Comment + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Type) { + toSerialize["type"] = o.Type + } + return toSerialize, nil +} + +type NullableDtoCreateSSHRequest struct { + value *DtoCreateSSHRequest + isSet bool +} + +func (v NullableDtoCreateSSHRequest) Get() *DtoCreateSSHRequest { + return v.value +} + +func (v *NullableDtoCreateSSHRequest) Set(val *DtoCreateSSHRequest) { + v.value = val + v.isSet = true +} + +func (v NullableDtoCreateSSHRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoCreateSSHRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoCreateSSHRequest(val *DtoCreateSSHRequest) *NullableDtoCreateSSHRequest { + return &NullableDtoCreateSSHRequest{value: val, isSet: true} +} + +func (v NullableDtoCreateSSHRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoCreateSSHRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_create_taint_request.go b/sdk/go/model_dto_create_taint_request.go new file mode 100644 index 0000000..3293a00 --- /dev/null +++ b/sdk/go/model_dto_create_taint_request.go @@ -0,0 +1,196 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoCreateTaintRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoCreateTaintRequest{} + +// DtoCreateTaintRequest struct for DtoCreateTaintRequest +type DtoCreateTaintRequest struct { + Effect *string `json:"effect,omitempty"` + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +// NewDtoCreateTaintRequest instantiates a new DtoCreateTaintRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoCreateTaintRequest() *DtoCreateTaintRequest { + this := DtoCreateTaintRequest{} + return &this +} + +// NewDtoCreateTaintRequestWithDefaults instantiates a new DtoCreateTaintRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoCreateTaintRequestWithDefaults() *DtoCreateTaintRequest { + this := DtoCreateTaintRequest{} + return &this +} + +// GetEffect returns the Effect field value if set, zero value otherwise. +func (o *DtoCreateTaintRequest) GetEffect() string { + if o == nil || IsNil(o.Effect) { + var ret string + return ret + } + return *o.Effect +} + +// GetEffectOk returns a tuple with the Effect field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateTaintRequest) GetEffectOk() (*string, bool) { + if o == nil || IsNil(o.Effect) { + return nil, false + } + return o.Effect, true +} + +// HasEffect returns a boolean if a field has been set. +func (o *DtoCreateTaintRequest) HasEffect() bool { + if o != nil && !IsNil(o.Effect) { + return true + } + + return false +} + +// SetEffect gets a reference to the given string and assigns it to the Effect field. +func (o *DtoCreateTaintRequest) SetEffect(v string) { + o.Effect = &v +} + +// GetKey returns the Key field value if set, zero value otherwise. +func (o *DtoCreateTaintRequest) GetKey() string { + if o == nil || IsNil(o.Key) { + var ret string + return ret + } + return *o.Key +} + +// GetKeyOk returns a tuple with the Key field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateTaintRequest) GetKeyOk() (*string, bool) { + if o == nil || IsNil(o.Key) { + return nil, false + } + return o.Key, true +} + +// HasKey returns a boolean if a field has been set. +func (o *DtoCreateTaintRequest) HasKey() bool { + if o != nil && !IsNil(o.Key) { + return true + } + + return false +} + +// SetKey gets a reference to the given string and assigns it to the Key field. +func (o *DtoCreateTaintRequest) SetKey(v string) { + o.Key = &v +} + +// GetValue returns the Value field value if set, zero value otherwise. +func (o *DtoCreateTaintRequest) GetValue() string { + if o == nil || IsNil(o.Value) { + var ret string + return ret + } + return *o.Value +} + +// GetValueOk returns a tuple with the Value field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoCreateTaintRequest) GetValueOk() (*string, bool) { + if o == nil || IsNil(o.Value) { + return nil, false + } + return o.Value, true +} + +// HasValue returns a boolean if a field has been set. +func (o *DtoCreateTaintRequest) HasValue() bool { + if o != nil && !IsNil(o.Value) { + return true + } + + return false +} + +// SetValue gets a reference to the given string and assigns it to the Value field. +func (o *DtoCreateTaintRequest) SetValue(v string) { + o.Value = &v +} + +func (o DtoCreateTaintRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoCreateTaintRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Effect) { + toSerialize["effect"] = o.Effect + } + if !IsNil(o.Key) { + toSerialize["key"] = o.Key + } + if !IsNil(o.Value) { + toSerialize["value"] = o.Value + } + return toSerialize, nil +} + +type NullableDtoCreateTaintRequest struct { + value *DtoCreateTaintRequest + isSet bool +} + +func (v NullableDtoCreateTaintRequest) Get() *DtoCreateTaintRequest { + return v.value +} + +func (v *NullableDtoCreateTaintRequest) Set(val *DtoCreateTaintRequest) { + v.value = val + v.isSet = true +} + +func (v NullableDtoCreateTaintRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoCreateTaintRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoCreateTaintRequest(val *DtoCreateTaintRequest) *NullableDtoCreateTaintRequest { + return &NullableDtoCreateTaintRequest{value: val, isSet: true} +} + +func (v NullableDtoCreateTaintRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoCreateTaintRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_jwk.go b/sdk/go/model_dto_jwk.go new file mode 100644 index 0000000..f04bdc6 --- /dev/null +++ b/sdk/go/model_dto_jwk.go @@ -0,0 +1,340 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoJWK type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoJWK{} + +// DtoJWK struct for DtoJWK +type DtoJWK struct { + Alg *string `json:"alg,omitempty"` + E *string `json:"e,omitempty"` + Kid *string `json:"kid,omitempty"` + Kty *string `json:"kty,omitempty"` + N *string `json:"n,omitempty"` + Use *string `json:"use,omitempty"` + X *string `json:"x,omitempty"` +} + +// NewDtoJWK instantiates a new DtoJWK object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoJWK() *DtoJWK { + this := DtoJWK{} + return &this +} + +// NewDtoJWKWithDefaults instantiates a new DtoJWK object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoJWKWithDefaults() *DtoJWK { + this := DtoJWK{} + return &this +} + +// GetAlg returns the Alg field value if set, zero value otherwise. +func (o *DtoJWK) GetAlg() string { + if o == nil || IsNil(o.Alg) { + var ret string + return ret + } + return *o.Alg +} + +// GetAlgOk returns a tuple with the Alg field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoJWK) GetAlgOk() (*string, bool) { + if o == nil || IsNil(o.Alg) { + return nil, false + } + return o.Alg, true +} + +// HasAlg returns a boolean if a field has been set. +func (o *DtoJWK) HasAlg() bool { + if o != nil && !IsNil(o.Alg) { + return true + } + + return false +} + +// SetAlg gets a reference to the given string and assigns it to the Alg field. +func (o *DtoJWK) SetAlg(v string) { + o.Alg = &v +} + +// GetE returns the E field value if set, zero value otherwise. +func (o *DtoJWK) GetE() string { + if o == nil || IsNil(o.E) { + var ret string + return ret + } + return *o.E +} + +// GetEOk returns a tuple with the E field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoJWK) GetEOk() (*string, bool) { + if o == nil || IsNil(o.E) { + return nil, false + } + return o.E, true +} + +// HasE returns a boolean if a field has been set. +func (o *DtoJWK) HasE() bool { + if o != nil && !IsNil(o.E) { + return true + } + + return false +} + +// SetE gets a reference to the given string and assigns it to the E field. +func (o *DtoJWK) SetE(v string) { + o.E = &v +} + +// GetKid returns the Kid field value if set, zero value otherwise. +func (o *DtoJWK) GetKid() string { + if o == nil || IsNil(o.Kid) { + var ret string + return ret + } + return *o.Kid +} + +// GetKidOk returns a tuple with the Kid field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoJWK) GetKidOk() (*string, bool) { + if o == nil || IsNil(o.Kid) { + return nil, false + } + return o.Kid, true +} + +// HasKid returns a boolean if a field has been set. +func (o *DtoJWK) HasKid() bool { + if o != nil && !IsNil(o.Kid) { + return true + } + + return false +} + +// SetKid gets a reference to the given string and assigns it to the Kid field. +func (o *DtoJWK) SetKid(v string) { + o.Kid = &v +} + +// GetKty returns the Kty field value if set, zero value otherwise. +func (o *DtoJWK) GetKty() string { + if o == nil || IsNil(o.Kty) { + var ret string + return ret + } + return *o.Kty +} + +// GetKtyOk returns a tuple with the Kty field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoJWK) GetKtyOk() (*string, bool) { + if o == nil || IsNil(o.Kty) { + return nil, false + } + return o.Kty, true +} + +// HasKty returns a boolean if a field has been set. +func (o *DtoJWK) HasKty() bool { + if o != nil && !IsNil(o.Kty) { + return true + } + + return false +} + +// SetKty gets a reference to the given string and assigns it to the Kty field. +func (o *DtoJWK) SetKty(v string) { + o.Kty = &v +} + +// GetN returns the N field value if set, zero value otherwise. +func (o *DtoJWK) GetN() string { + if o == nil || IsNil(o.N) { + var ret string + return ret + } + return *o.N +} + +// GetNOk returns a tuple with the N field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoJWK) GetNOk() (*string, bool) { + if o == nil || IsNil(o.N) { + return nil, false + } + return o.N, true +} + +// HasN returns a boolean if a field has been set. +func (o *DtoJWK) HasN() bool { + if o != nil && !IsNil(o.N) { + return true + } + + return false +} + +// SetN gets a reference to the given string and assigns it to the N field. +func (o *DtoJWK) SetN(v string) { + o.N = &v +} + +// GetUse returns the Use field value if set, zero value otherwise. +func (o *DtoJWK) GetUse() string { + if o == nil || IsNil(o.Use) { + var ret string + return ret + } + return *o.Use +} + +// GetUseOk returns a tuple with the Use field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoJWK) GetUseOk() (*string, bool) { + if o == nil || IsNil(o.Use) { + return nil, false + } + return o.Use, true +} + +// HasUse returns a boolean if a field has been set. +func (o *DtoJWK) HasUse() bool { + if o != nil && !IsNil(o.Use) { + return true + } + + return false +} + +// SetUse gets a reference to the given string and assigns it to the Use field. +func (o *DtoJWK) SetUse(v string) { + o.Use = &v +} + +// GetX returns the X field value if set, zero value otherwise. +func (o *DtoJWK) GetX() string { + if o == nil || IsNil(o.X) { + var ret string + return ret + } + return *o.X +} + +// GetXOk returns a tuple with the X field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoJWK) GetXOk() (*string, bool) { + if o == nil || IsNil(o.X) { + return nil, false + } + return o.X, true +} + +// HasX returns a boolean if a field has been set. +func (o *DtoJWK) HasX() bool { + if o != nil && !IsNil(o.X) { + return true + } + + return false +} + +// SetX gets a reference to the given string and assigns it to the X field. +func (o *DtoJWK) SetX(v string) { + o.X = &v +} + +func (o DtoJWK) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoJWK) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Alg) { + toSerialize["alg"] = o.Alg + } + if !IsNil(o.E) { + toSerialize["e"] = o.E + } + if !IsNil(o.Kid) { + toSerialize["kid"] = o.Kid + } + if !IsNil(o.Kty) { + toSerialize["kty"] = o.Kty + } + if !IsNil(o.N) { + toSerialize["n"] = o.N + } + if !IsNil(o.Use) { + toSerialize["use"] = o.Use + } + if !IsNil(o.X) { + toSerialize["x"] = o.X + } + return toSerialize, nil +} + +type NullableDtoJWK struct { + value *DtoJWK + isSet bool +} + +func (v NullableDtoJWK) Get() *DtoJWK { + return v.value +} + +func (v *NullableDtoJWK) Set(val *DtoJWK) { + v.value = val + v.isSet = true +} + +func (v NullableDtoJWK) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoJWK) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoJWK(val *DtoJWK) *NullableDtoJWK { + return &NullableDtoJWK{value: val, isSet: true} +} + +func (v NullableDtoJWK) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoJWK) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_jwks.go b/sdk/go/model_dto_jwks.go new file mode 100644 index 0000000..a66ecf1 --- /dev/null +++ b/sdk/go/model_dto_jwks.go @@ -0,0 +1,124 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoJWKS type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoJWKS{} + +// DtoJWKS struct for DtoJWKS +type DtoJWKS struct { + Keys []DtoJWK `json:"keys,omitempty"` +} + +// NewDtoJWKS instantiates a new DtoJWKS object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoJWKS() *DtoJWKS { + this := DtoJWKS{} + return &this +} + +// NewDtoJWKSWithDefaults instantiates a new DtoJWKS object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoJWKSWithDefaults() *DtoJWKS { + this := DtoJWKS{} + return &this +} + +// GetKeys returns the Keys field value if set, zero value otherwise. +func (o *DtoJWKS) GetKeys() []DtoJWK { + if o == nil || IsNil(o.Keys) { + var ret []DtoJWK + return ret + } + return o.Keys +} + +// GetKeysOk returns a tuple with the Keys field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoJWKS) GetKeysOk() ([]DtoJWK, bool) { + if o == nil || IsNil(o.Keys) { + return nil, false + } + return o.Keys, true +} + +// HasKeys returns a boolean if a field has been set. +func (o *DtoJWKS) HasKeys() bool { + if o != nil && !IsNil(o.Keys) { + return true + } + + return false +} + +// SetKeys gets a reference to the given []DtoJWK and assigns it to the Keys field. +func (o *DtoJWKS) SetKeys(v []DtoJWK) { + o.Keys = v +} + +func (o DtoJWKS) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoJWKS) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Keys) { + toSerialize["keys"] = o.Keys + } + return toSerialize, nil +} + +type NullableDtoJWKS struct { + value *DtoJWKS + isSet bool +} + +func (v NullableDtoJWKS) Get() *DtoJWKS { + return v.value +} + +func (v *NullableDtoJWKS) Set(val *DtoJWKS) { + v.value = val + v.isSet = true +} + +func (v NullableDtoJWKS) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoJWKS) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoJWKS(val *DtoJWKS) *NullableDtoJWKS { + return &NullableDtoJWKS{value: val, isSet: true} +} + +func (v NullableDtoJWKS) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoJWKS) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_logout_request.go b/sdk/go/model_dto_logout_request.go new file mode 100644 index 0000000..a874279 --- /dev/null +++ b/sdk/go/model_dto_logout_request.go @@ -0,0 +1,124 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoLogoutRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoLogoutRequest{} + +// DtoLogoutRequest struct for DtoLogoutRequest +type DtoLogoutRequest struct { + RefreshToken *string `json:"refresh_token,omitempty"` +} + +// NewDtoLogoutRequest instantiates a new DtoLogoutRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoLogoutRequest() *DtoLogoutRequest { + this := DtoLogoutRequest{} + return &this +} + +// NewDtoLogoutRequestWithDefaults instantiates a new DtoLogoutRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoLogoutRequestWithDefaults() *DtoLogoutRequest { + this := DtoLogoutRequest{} + return &this +} + +// GetRefreshToken returns the RefreshToken field value if set, zero value otherwise. +func (o *DtoLogoutRequest) GetRefreshToken() string { + if o == nil || IsNil(o.RefreshToken) { + var ret string + return ret + } + return *o.RefreshToken +} + +// GetRefreshTokenOk returns a tuple with the RefreshToken field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoLogoutRequest) GetRefreshTokenOk() (*string, bool) { + if o == nil || IsNil(o.RefreshToken) { + return nil, false + } + return o.RefreshToken, true +} + +// HasRefreshToken returns a boolean if a field has been set. +func (o *DtoLogoutRequest) HasRefreshToken() bool { + if o != nil && !IsNil(o.RefreshToken) { + return true + } + + return false +} + +// SetRefreshToken gets a reference to the given string and assigns it to the RefreshToken field. +func (o *DtoLogoutRequest) SetRefreshToken(v string) { + o.RefreshToken = &v +} + +func (o DtoLogoutRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoLogoutRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.RefreshToken) { + toSerialize["refresh_token"] = o.RefreshToken + } + return toSerialize, nil +} + +type NullableDtoLogoutRequest struct { + value *DtoLogoutRequest + isSet bool +} + +func (v NullableDtoLogoutRequest) Get() *DtoLogoutRequest { + return v.value +} + +func (v *NullableDtoLogoutRequest) Set(val *DtoLogoutRequest) { + v.value = val + v.isSet = true +} + +func (v NullableDtoLogoutRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoLogoutRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoLogoutRequest(val *DtoLogoutRequest) *NullableDtoLogoutRequest { + return &NullableDtoLogoutRequest{value: val, isSet: true} +} + +func (v NullableDtoLogoutRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoLogoutRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_refresh_request.go b/sdk/go/model_dto_refresh_request.go new file mode 100644 index 0000000..bce052d --- /dev/null +++ b/sdk/go/model_dto_refresh_request.go @@ -0,0 +1,124 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoRefreshRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoRefreshRequest{} + +// DtoRefreshRequest struct for DtoRefreshRequest +type DtoRefreshRequest struct { + RefreshToken *string `json:"refresh_token,omitempty"` +} + +// NewDtoRefreshRequest instantiates a new DtoRefreshRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoRefreshRequest() *DtoRefreshRequest { + this := DtoRefreshRequest{} + return &this +} + +// NewDtoRefreshRequestWithDefaults instantiates a new DtoRefreshRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoRefreshRequestWithDefaults() *DtoRefreshRequest { + this := DtoRefreshRequest{} + return &this +} + +// GetRefreshToken returns the RefreshToken field value if set, zero value otherwise. +func (o *DtoRefreshRequest) GetRefreshToken() string { + if o == nil || IsNil(o.RefreshToken) { + var ret string + return ret + } + return *o.RefreshToken +} + +// GetRefreshTokenOk returns a tuple with the RefreshToken field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoRefreshRequest) GetRefreshTokenOk() (*string, bool) { + if o == nil || IsNil(o.RefreshToken) { + return nil, false + } + return o.RefreshToken, true +} + +// HasRefreshToken returns a boolean if a field has been set. +func (o *DtoRefreshRequest) HasRefreshToken() bool { + if o != nil && !IsNil(o.RefreshToken) { + return true + } + + return false +} + +// SetRefreshToken gets a reference to the given string and assigns it to the RefreshToken field. +func (o *DtoRefreshRequest) SetRefreshToken(v string) { + o.RefreshToken = &v +} + +func (o DtoRefreshRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoRefreshRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.RefreshToken) { + toSerialize["refresh_token"] = o.RefreshToken + } + return toSerialize, nil +} + +type NullableDtoRefreshRequest struct { + value *DtoRefreshRequest + isSet bool +} + +func (v NullableDtoRefreshRequest) Get() *DtoRefreshRequest { + return v.value +} + +func (v *NullableDtoRefreshRequest) Set(val *DtoRefreshRequest) { + v.value = val + v.isSet = true +} + +func (v NullableDtoRefreshRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoRefreshRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoRefreshRequest(val *DtoRefreshRequest) *NullableDtoRefreshRequest { + return &NullableDtoRefreshRequest{value: val, isSet: true} +} + +func (v NullableDtoRefreshRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoRefreshRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_server_response.go b/sdk/go/model_dto_server_response.go new file mode 100644 index 0000000..e4d5665 --- /dev/null +++ b/sdk/go/model_dto_server_response.go @@ -0,0 +1,484 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoServerResponse type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoServerResponse{} + +// DtoServerResponse struct for DtoServerResponse +type DtoServerResponse struct { + CreatedAt *string `json:"created_at,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Id *string `json:"id,omitempty"` + OrganizationId *string `json:"organization_id,omitempty"` + PrivateIpAddress *string `json:"private_ip_address,omitempty"` + PublicIpAddress *string `json:"public_ip_address,omitempty"` + Role *string `json:"role,omitempty"` + SshKeyId *string `json:"ssh_key_id,omitempty"` + SshUser *string `json:"ssh_user,omitempty"` + Status *string `json:"status,omitempty"` + UpdatedAt *string `json:"updated_at,omitempty"` +} + +// NewDtoServerResponse instantiates a new DtoServerResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoServerResponse() *DtoServerResponse { + this := DtoServerResponse{} + return &this +} + +// NewDtoServerResponseWithDefaults instantiates a new DtoServerResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoServerResponseWithDefaults() *DtoServerResponse { + this := DtoServerResponse{} + return &this +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *DtoServerResponse) GetCreatedAt() string { + if o == nil || IsNil(o.CreatedAt) { + var ret string + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetCreatedAtOk() (*string, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *DtoServerResponse) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given string and assigns it to the CreatedAt field. +func (o *DtoServerResponse) SetCreatedAt(v string) { + o.CreatedAt = &v +} + +// GetHostname returns the Hostname field value if set, zero value otherwise. +func (o *DtoServerResponse) GetHostname() string { + if o == nil || IsNil(o.Hostname) { + var ret string + return ret + } + return *o.Hostname +} + +// GetHostnameOk returns a tuple with the Hostname field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetHostnameOk() (*string, bool) { + if o == nil || IsNil(o.Hostname) { + return nil, false + } + return o.Hostname, true +} + +// HasHostname returns a boolean if a field has been set. +func (o *DtoServerResponse) HasHostname() bool { + if o != nil && !IsNil(o.Hostname) { + return true + } + + return false +} + +// SetHostname gets a reference to the given string and assigns it to the Hostname field. +func (o *DtoServerResponse) SetHostname(v string) { + o.Hostname = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *DtoServerResponse) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *DtoServerResponse) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *DtoServerResponse) SetId(v string) { + o.Id = &v +} + +// GetOrganizationId returns the OrganizationId field value if set, zero value otherwise. +func (o *DtoServerResponse) GetOrganizationId() string { + if o == nil || IsNil(o.OrganizationId) { + var ret string + return ret + } + return *o.OrganizationId +} + +// GetOrganizationIdOk returns a tuple with the OrganizationId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetOrganizationIdOk() (*string, bool) { + if o == nil || IsNil(o.OrganizationId) { + return nil, false + } + return o.OrganizationId, true +} + +// HasOrganizationId returns a boolean if a field has been set. +func (o *DtoServerResponse) HasOrganizationId() bool { + if o != nil && !IsNil(o.OrganizationId) { + return true + } + + return false +} + +// SetOrganizationId gets a reference to the given string and assigns it to the OrganizationId field. +func (o *DtoServerResponse) SetOrganizationId(v string) { + o.OrganizationId = &v +} + +// GetPrivateIpAddress returns the PrivateIpAddress field value if set, zero value otherwise. +func (o *DtoServerResponse) GetPrivateIpAddress() string { + if o == nil || IsNil(o.PrivateIpAddress) { + var ret string + return ret + } + return *o.PrivateIpAddress +} + +// GetPrivateIpAddressOk returns a tuple with the PrivateIpAddress field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetPrivateIpAddressOk() (*string, bool) { + if o == nil || IsNil(o.PrivateIpAddress) { + return nil, false + } + return o.PrivateIpAddress, true +} + +// HasPrivateIpAddress returns a boolean if a field has been set. +func (o *DtoServerResponse) HasPrivateIpAddress() bool { + if o != nil && !IsNil(o.PrivateIpAddress) { + return true + } + + return false +} + +// SetPrivateIpAddress gets a reference to the given string and assigns it to the PrivateIpAddress field. +func (o *DtoServerResponse) SetPrivateIpAddress(v string) { + o.PrivateIpAddress = &v +} + +// GetPublicIpAddress returns the PublicIpAddress field value if set, zero value otherwise. +func (o *DtoServerResponse) GetPublicIpAddress() string { + if o == nil || IsNil(o.PublicIpAddress) { + var ret string + return ret + } + return *o.PublicIpAddress +} + +// GetPublicIpAddressOk returns a tuple with the PublicIpAddress field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetPublicIpAddressOk() (*string, bool) { + if o == nil || IsNil(o.PublicIpAddress) { + return nil, false + } + return o.PublicIpAddress, true +} + +// HasPublicIpAddress returns a boolean if a field has been set. +func (o *DtoServerResponse) HasPublicIpAddress() bool { + if o != nil && !IsNil(o.PublicIpAddress) { + return true + } + + return false +} + +// SetPublicIpAddress gets a reference to the given string and assigns it to the PublicIpAddress field. +func (o *DtoServerResponse) SetPublicIpAddress(v string) { + o.PublicIpAddress = &v +} + +// GetRole returns the Role field value if set, zero value otherwise. +func (o *DtoServerResponse) GetRole() string { + if o == nil || IsNil(o.Role) { + var ret string + return ret + } + return *o.Role +} + +// GetRoleOk returns a tuple with the Role field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetRoleOk() (*string, bool) { + if o == nil || IsNil(o.Role) { + return nil, false + } + return o.Role, true +} + +// HasRole returns a boolean if a field has been set. +func (o *DtoServerResponse) HasRole() bool { + if o != nil && !IsNil(o.Role) { + return true + } + + return false +} + +// SetRole gets a reference to the given string and assigns it to the Role field. +func (o *DtoServerResponse) SetRole(v string) { + o.Role = &v +} + +// GetSshKeyId returns the SshKeyId field value if set, zero value otherwise. +func (o *DtoServerResponse) GetSshKeyId() string { + if o == nil || IsNil(o.SshKeyId) { + var ret string + return ret + } + return *o.SshKeyId +} + +// GetSshKeyIdOk returns a tuple with the SshKeyId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetSshKeyIdOk() (*string, bool) { + if o == nil || IsNil(o.SshKeyId) { + return nil, false + } + return o.SshKeyId, true +} + +// HasSshKeyId returns a boolean if a field has been set. +func (o *DtoServerResponse) HasSshKeyId() bool { + if o != nil && !IsNil(o.SshKeyId) { + return true + } + + return false +} + +// SetSshKeyId gets a reference to the given string and assigns it to the SshKeyId field. +func (o *DtoServerResponse) SetSshKeyId(v string) { + o.SshKeyId = &v +} + +// GetSshUser returns the SshUser field value if set, zero value otherwise. +func (o *DtoServerResponse) GetSshUser() string { + if o == nil || IsNil(o.SshUser) { + var ret string + return ret + } + return *o.SshUser +} + +// GetSshUserOk returns a tuple with the SshUser field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetSshUserOk() (*string, bool) { + if o == nil || IsNil(o.SshUser) { + return nil, false + } + return o.SshUser, true +} + +// HasSshUser returns a boolean if a field has been set. +func (o *DtoServerResponse) HasSshUser() bool { + if o != nil && !IsNil(o.SshUser) { + return true + } + + return false +} + +// SetSshUser gets a reference to the given string and assigns it to the SshUser field. +func (o *DtoServerResponse) SetSshUser(v string) { + o.SshUser = &v +} + +// GetStatus returns the Status field value if set, zero value otherwise. +func (o *DtoServerResponse) GetStatus() string { + if o == nil || IsNil(o.Status) { + var ret string + return ret + } + return *o.Status +} + +// GetStatusOk returns a tuple with the Status field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetStatusOk() (*string, bool) { + if o == nil || IsNil(o.Status) { + return nil, false + } + return o.Status, true +} + +// HasStatus returns a boolean if a field has been set. +func (o *DtoServerResponse) HasStatus() bool { + if o != nil && !IsNil(o.Status) { + return true + } + + return false +} + +// SetStatus gets a reference to the given string and assigns it to the Status field. +func (o *DtoServerResponse) SetStatus(v string) { + o.Status = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *DtoServerResponse) GetUpdatedAt() string { + if o == nil || IsNil(o.UpdatedAt) { + var ret string + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoServerResponse) GetUpdatedAtOk() (*string, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *DtoServerResponse) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given string and assigns it to the UpdatedAt field. +func (o *DtoServerResponse) SetUpdatedAt(v string) { + o.UpdatedAt = &v +} + +func (o DtoServerResponse) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoServerResponse) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.Hostname) { + toSerialize["hostname"] = o.Hostname + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.OrganizationId) { + toSerialize["organization_id"] = o.OrganizationId + } + if !IsNil(o.PrivateIpAddress) { + toSerialize["private_ip_address"] = o.PrivateIpAddress + } + if !IsNil(o.PublicIpAddress) { + toSerialize["public_ip_address"] = o.PublicIpAddress + } + if !IsNil(o.Role) { + toSerialize["role"] = o.Role + } + if !IsNil(o.SshKeyId) { + toSerialize["ssh_key_id"] = o.SshKeyId + } + if !IsNil(o.SshUser) { + toSerialize["ssh_user"] = o.SshUser + } + if !IsNil(o.Status) { + toSerialize["status"] = o.Status + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + return toSerialize, nil +} + +type NullableDtoServerResponse struct { + value *DtoServerResponse + isSet bool +} + +func (v NullableDtoServerResponse) Get() *DtoServerResponse { + return v.value +} + +func (v *NullableDtoServerResponse) Set(val *DtoServerResponse) { + v.value = val + v.isSet = true +} + +func (v NullableDtoServerResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoServerResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoServerResponse(val *DtoServerResponse) *NullableDtoServerResponse { + return &NullableDtoServerResponse{value: val, isSet: true} +} + +func (v NullableDtoServerResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoServerResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_ssh_response.go b/sdk/go/model_dto_ssh_response.go new file mode 100644 index 0000000..d53c4f3 --- /dev/null +++ b/sdk/go/model_dto_ssh_response.go @@ -0,0 +1,340 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoSshResponse type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoSshResponse{} + +// DtoSshResponse struct for DtoSshResponse +type DtoSshResponse struct { + CreatedAt *string `json:"created_at,omitempty"` + Fingerprint *string `json:"fingerprint,omitempty"` + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + OrganizationId *string `json:"organization_id,omitempty"` + PublicKey *string `json:"public_key,omitempty"` + UpdatedAt *string `json:"updated_at,omitempty"` +} + +// NewDtoSshResponse instantiates a new DtoSshResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoSshResponse() *DtoSshResponse { + this := DtoSshResponse{} + return &this +} + +// NewDtoSshResponseWithDefaults instantiates a new DtoSshResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoSshResponseWithDefaults() *DtoSshResponse { + this := DtoSshResponse{} + return &this +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *DtoSshResponse) GetCreatedAt() string { + if o == nil || IsNil(o.CreatedAt) { + var ret string + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshResponse) GetCreatedAtOk() (*string, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *DtoSshResponse) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given string and assigns it to the CreatedAt field. +func (o *DtoSshResponse) SetCreatedAt(v string) { + o.CreatedAt = &v +} + +// GetFingerprint returns the Fingerprint field value if set, zero value otherwise. +func (o *DtoSshResponse) GetFingerprint() string { + if o == nil || IsNil(o.Fingerprint) { + var ret string + return ret + } + return *o.Fingerprint +} + +// GetFingerprintOk returns a tuple with the Fingerprint field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshResponse) GetFingerprintOk() (*string, bool) { + if o == nil || IsNil(o.Fingerprint) { + return nil, false + } + return o.Fingerprint, true +} + +// HasFingerprint returns a boolean if a field has been set. +func (o *DtoSshResponse) HasFingerprint() bool { + if o != nil && !IsNil(o.Fingerprint) { + return true + } + + return false +} + +// SetFingerprint gets a reference to the given string and assigns it to the Fingerprint field. +func (o *DtoSshResponse) SetFingerprint(v string) { + o.Fingerprint = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *DtoSshResponse) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshResponse) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *DtoSshResponse) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *DtoSshResponse) SetId(v string) { + o.Id = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *DtoSshResponse) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshResponse) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *DtoSshResponse) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *DtoSshResponse) SetName(v string) { + o.Name = &v +} + +// GetOrganizationId returns the OrganizationId field value if set, zero value otherwise. +func (o *DtoSshResponse) GetOrganizationId() string { + if o == nil || IsNil(o.OrganizationId) { + var ret string + return ret + } + return *o.OrganizationId +} + +// GetOrganizationIdOk returns a tuple with the OrganizationId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshResponse) GetOrganizationIdOk() (*string, bool) { + if o == nil || IsNil(o.OrganizationId) { + return nil, false + } + return o.OrganizationId, true +} + +// HasOrganizationId returns a boolean if a field has been set. +func (o *DtoSshResponse) HasOrganizationId() bool { + if o != nil && !IsNil(o.OrganizationId) { + return true + } + + return false +} + +// SetOrganizationId gets a reference to the given string and assigns it to the OrganizationId field. +func (o *DtoSshResponse) SetOrganizationId(v string) { + o.OrganizationId = &v +} + +// GetPublicKey returns the PublicKey field value if set, zero value otherwise. +func (o *DtoSshResponse) GetPublicKey() string { + if o == nil || IsNil(o.PublicKey) { + var ret string + return ret + } + return *o.PublicKey +} + +// GetPublicKeyOk returns a tuple with the PublicKey field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshResponse) GetPublicKeyOk() (*string, bool) { + if o == nil || IsNil(o.PublicKey) { + return nil, false + } + return o.PublicKey, true +} + +// HasPublicKey returns a boolean if a field has been set. +func (o *DtoSshResponse) HasPublicKey() bool { + if o != nil && !IsNil(o.PublicKey) { + return true + } + + return false +} + +// SetPublicKey gets a reference to the given string and assigns it to the PublicKey field. +func (o *DtoSshResponse) SetPublicKey(v string) { + o.PublicKey = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *DtoSshResponse) GetUpdatedAt() string { + if o == nil || IsNil(o.UpdatedAt) { + var ret string + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshResponse) GetUpdatedAtOk() (*string, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *DtoSshResponse) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given string and assigns it to the UpdatedAt field. +func (o *DtoSshResponse) SetUpdatedAt(v string) { + o.UpdatedAt = &v +} + +func (o DtoSshResponse) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoSshResponse) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.Fingerprint) { + toSerialize["fingerprint"] = o.Fingerprint + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.OrganizationId) { + toSerialize["organization_id"] = o.OrganizationId + } + if !IsNil(o.PublicKey) { + toSerialize["public_key"] = o.PublicKey + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + return toSerialize, nil +} + +type NullableDtoSshResponse struct { + value *DtoSshResponse + isSet bool +} + +func (v NullableDtoSshResponse) Get() *DtoSshResponse { + return v.value +} + +func (v *NullableDtoSshResponse) Set(val *DtoSshResponse) { + v.value = val + v.isSet = true +} + +func (v NullableDtoSshResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoSshResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoSshResponse(val *DtoSshResponse) *NullableDtoSshResponse { + return &NullableDtoSshResponse{value: val, isSet: true} +} + +func (v NullableDtoSshResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoSshResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_ssh_reveal_response.go b/sdk/go/model_dto_ssh_reveal_response.go new file mode 100644 index 0000000..b3eba6f --- /dev/null +++ b/sdk/go/model_dto_ssh_reveal_response.go @@ -0,0 +1,376 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoSshRevealResponse type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoSshRevealResponse{} + +// DtoSshRevealResponse struct for DtoSshRevealResponse +type DtoSshRevealResponse struct { + CreatedAt *string `json:"created_at,omitempty"` + Fingerprint *string `json:"fingerprint,omitempty"` + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + OrganizationId *string `json:"organization_id,omitempty"` + PrivateKey *string `json:"private_key,omitempty"` + PublicKey *string `json:"public_key,omitempty"` + UpdatedAt *string `json:"updated_at,omitempty"` +} + +// NewDtoSshRevealResponse instantiates a new DtoSshRevealResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoSshRevealResponse() *DtoSshRevealResponse { + this := DtoSshRevealResponse{} + return &this +} + +// NewDtoSshRevealResponseWithDefaults instantiates a new DtoSshRevealResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoSshRevealResponseWithDefaults() *DtoSshRevealResponse { + this := DtoSshRevealResponse{} + return &this +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *DtoSshRevealResponse) GetCreatedAt() string { + if o == nil || IsNil(o.CreatedAt) { + var ret string + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshRevealResponse) GetCreatedAtOk() (*string, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *DtoSshRevealResponse) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given string and assigns it to the CreatedAt field. +func (o *DtoSshRevealResponse) SetCreatedAt(v string) { + o.CreatedAt = &v +} + +// GetFingerprint returns the Fingerprint field value if set, zero value otherwise. +func (o *DtoSshRevealResponse) GetFingerprint() string { + if o == nil || IsNil(o.Fingerprint) { + var ret string + return ret + } + return *o.Fingerprint +} + +// GetFingerprintOk returns a tuple with the Fingerprint field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshRevealResponse) GetFingerprintOk() (*string, bool) { + if o == nil || IsNil(o.Fingerprint) { + return nil, false + } + return o.Fingerprint, true +} + +// HasFingerprint returns a boolean if a field has been set. +func (o *DtoSshRevealResponse) HasFingerprint() bool { + if o != nil && !IsNil(o.Fingerprint) { + return true + } + + return false +} + +// SetFingerprint gets a reference to the given string and assigns it to the Fingerprint field. +func (o *DtoSshRevealResponse) SetFingerprint(v string) { + o.Fingerprint = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *DtoSshRevealResponse) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshRevealResponse) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *DtoSshRevealResponse) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *DtoSshRevealResponse) SetId(v string) { + o.Id = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *DtoSshRevealResponse) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshRevealResponse) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *DtoSshRevealResponse) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *DtoSshRevealResponse) SetName(v string) { + o.Name = &v +} + +// GetOrganizationId returns the OrganizationId field value if set, zero value otherwise. +func (o *DtoSshRevealResponse) GetOrganizationId() string { + if o == nil || IsNil(o.OrganizationId) { + var ret string + return ret + } + return *o.OrganizationId +} + +// GetOrganizationIdOk returns a tuple with the OrganizationId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshRevealResponse) GetOrganizationIdOk() (*string, bool) { + if o == nil || IsNil(o.OrganizationId) { + return nil, false + } + return o.OrganizationId, true +} + +// HasOrganizationId returns a boolean if a field has been set. +func (o *DtoSshRevealResponse) HasOrganizationId() bool { + if o != nil && !IsNil(o.OrganizationId) { + return true + } + + return false +} + +// SetOrganizationId gets a reference to the given string and assigns it to the OrganizationId field. +func (o *DtoSshRevealResponse) SetOrganizationId(v string) { + o.OrganizationId = &v +} + +// GetPrivateKey returns the PrivateKey field value if set, zero value otherwise. +func (o *DtoSshRevealResponse) GetPrivateKey() string { + if o == nil || IsNil(o.PrivateKey) { + var ret string + return ret + } + return *o.PrivateKey +} + +// GetPrivateKeyOk returns a tuple with the PrivateKey field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshRevealResponse) GetPrivateKeyOk() (*string, bool) { + if o == nil || IsNil(o.PrivateKey) { + return nil, false + } + return o.PrivateKey, true +} + +// HasPrivateKey returns a boolean if a field has been set. +func (o *DtoSshRevealResponse) HasPrivateKey() bool { + if o != nil && !IsNil(o.PrivateKey) { + return true + } + + return false +} + +// SetPrivateKey gets a reference to the given string and assigns it to the PrivateKey field. +func (o *DtoSshRevealResponse) SetPrivateKey(v string) { + o.PrivateKey = &v +} + +// GetPublicKey returns the PublicKey field value if set, zero value otherwise. +func (o *DtoSshRevealResponse) GetPublicKey() string { + if o == nil || IsNil(o.PublicKey) { + var ret string + return ret + } + return *o.PublicKey +} + +// GetPublicKeyOk returns a tuple with the PublicKey field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshRevealResponse) GetPublicKeyOk() (*string, bool) { + if o == nil || IsNil(o.PublicKey) { + return nil, false + } + return o.PublicKey, true +} + +// HasPublicKey returns a boolean if a field has been set. +func (o *DtoSshRevealResponse) HasPublicKey() bool { + if o != nil && !IsNil(o.PublicKey) { + return true + } + + return false +} + +// SetPublicKey gets a reference to the given string and assigns it to the PublicKey field. +func (o *DtoSshRevealResponse) SetPublicKey(v string) { + o.PublicKey = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *DtoSshRevealResponse) GetUpdatedAt() string { + if o == nil || IsNil(o.UpdatedAt) { + var ret string + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoSshRevealResponse) GetUpdatedAtOk() (*string, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *DtoSshRevealResponse) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given string and assigns it to the UpdatedAt field. +func (o *DtoSshRevealResponse) SetUpdatedAt(v string) { + o.UpdatedAt = &v +} + +func (o DtoSshRevealResponse) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoSshRevealResponse) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.Fingerprint) { + toSerialize["fingerprint"] = o.Fingerprint + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.OrganizationId) { + toSerialize["organization_id"] = o.OrganizationId + } + if !IsNil(o.PrivateKey) { + toSerialize["private_key"] = o.PrivateKey + } + if !IsNil(o.PublicKey) { + toSerialize["public_key"] = o.PublicKey + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + return toSerialize, nil +} + +type NullableDtoSshRevealResponse struct { + value *DtoSshRevealResponse + isSet bool +} + +func (v NullableDtoSshRevealResponse) Get() *DtoSshRevealResponse { + return v.value +} + +func (v *NullableDtoSshRevealResponse) Set(val *DtoSshRevealResponse) { + v.value = val + v.isSet = true +} + +func (v NullableDtoSshRevealResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoSshRevealResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoSshRevealResponse(val *DtoSshRevealResponse) *NullableDtoSshRevealResponse { + return &NullableDtoSshRevealResponse{value: val, isSet: true} +} + +func (v NullableDtoSshRevealResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoSshRevealResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_taint_response.go b/sdk/go/model_dto_taint_response.go new file mode 100644 index 0000000..b9ec89f --- /dev/null +++ b/sdk/go/model_dto_taint_response.go @@ -0,0 +1,232 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoTaintResponse type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoTaintResponse{} + +// DtoTaintResponse struct for DtoTaintResponse +type DtoTaintResponse struct { + Effect *string `json:"effect,omitempty"` + Id *string `json:"id,omitempty"` + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +// NewDtoTaintResponse instantiates a new DtoTaintResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoTaintResponse() *DtoTaintResponse { + this := DtoTaintResponse{} + return &this +} + +// NewDtoTaintResponseWithDefaults instantiates a new DtoTaintResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoTaintResponseWithDefaults() *DtoTaintResponse { + this := DtoTaintResponse{} + return &this +} + +// GetEffect returns the Effect field value if set, zero value otherwise. +func (o *DtoTaintResponse) GetEffect() string { + if o == nil || IsNil(o.Effect) { + var ret string + return ret + } + return *o.Effect +} + +// GetEffectOk returns a tuple with the Effect field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoTaintResponse) GetEffectOk() (*string, bool) { + if o == nil || IsNil(o.Effect) { + return nil, false + } + return o.Effect, true +} + +// HasEffect returns a boolean if a field has been set. +func (o *DtoTaintResponse) HasEffect() bool { + if o != nil && !IsNil(o.Effect) { + return true + } + + return false +} + +// SetEffect gets a reference to the given string and assigns it to the Effect field. +func (o *DtoTaintResponse) SetEffect(v string) { + o.Effect = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *DtoTaintResponse) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoTaintResponse) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *DtoTaintResponse) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *DtoTaintResponse) SetId(v string) { + o.Id = &v +} + +// GetKey returns the Key field value if set, zero value otherwise. +func (o *DtoTaintResponse) GetKey() string { + if o == nil || IsNil(o.Key) { + var ret string + return ret + } + return *o.Key +} + +// GetKeyOk returns a tuple with the Key field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoTaintResponse) GetKeyOk() (*string, bool) { + if o == nil || IsNil(o.Key) { + return nil, false + } + return o.Key, true +} + +// HasKey returns a boolean if a field has been set. +func (o *DtoTaintResponse) HasKey() bool { + if o != nil && !IsNil(o.Key) { + return true + } + + return false +} + +// SetKey gets a reference to the given string and assigns it to the Key field. +func (o *DtoTaintResponse) SetKey(v string) { + o.Key = &v +} + +// GetValue returns the Value field value if set, zero value otherwise. +func (o *DtoTaintResponse) GetValue() string { + if o == nil || IsNil(o.Value) { + var ret string + return ret + } + return *o.Value +} + +// GetValueOk returns a tuple with the Value field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoTaintResponse) GetValueOk() (*string, bool) { + if o == nil || IsNil(o.Value) { + return nil, false + } + return o.Value, true +} + +// HasValue returns a boolean if a field has been set. +func (o *DtoTaintResponse) HasValue() bool { + if o != nil && !IsNil(o.Value) { + return true + } + + return false +} + +// SetValue gets a reference to the given string and assigns it to the Value field. +func (o *DtoTaintResponse) SetValue(v string) { + o.Value = &v +} + +func (o DtoTaintResponse) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoTaintResponse) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Effect) { + toSerialize["effect"] = o.Effect + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.Key) { + toSerialize["key"] = o.Key + } + if !IsNil(o.Value) { + toSerialize["value"] = o.Value + } + return toSerialize, nil +} + +type NullableDtoTaintResponse struct { + value *DtoTaintResponse + isSet bool +} + +func (v NullableDtoTaintResponse) Get() *DtoTaintResponse { + return v.value +} + +func (v *NullableDtoTaintResponse) Set(val *DtoTaintResponse) { + v.value = val + v.isSet = true +} + +func (v NullableDtoTaintResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoTaintResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoTaintResponse(val *DtoTaintResponse) *NullableDtoTaintResponse { + return &NullableDtoTaintResponse{value: val, isSet: true} +} + +func (v NullableDtoTaintResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoTaintResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_token_pair.go b/sdk/go/model_dto_token_pair.go new file mode 100644 index 0000000..120f4a7 --- /dev/null +++ b/sdk/go/model_dto_token_pair.go @@ -0,0 +1,232 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoTokenPair type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoTokenPair{} + +// DtoTokenPair struct for DtoTokenPair +type DtoTokenPair struct { + AccessToken *string `json:"access_token,omitempty"` + ExpiresIn *int32 `json:"expires_in,omitempty"` + RefreshToken *string `json:"refresh_token,omitempty"` + TokenType *string `json:"token_type,omitempty"` +} + +// NewDtoTokenPair instantiates a new DtoTokenPair object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoTokenPair() *DtoTokenPair { + this := DtoTokenPair{} + return &this +} + +// NewDtoTokenPairWithDefaults instantiates a new DtoTokenPair object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoTokenPairWithDefaults() *DtoTokenPair { + this := DtoTokenPair{} + return &this +} + +// GetAccessToken returns the AccessToken field value if set, zero value otherwise. +func (o *DtoTokenPair) GetAccessToken() string { + if o == nil || IsNil(o.AccessToken) { + var ret string + return ret + } + return *o.AccessToken +} + +// GetAccessTokenOk returns a tuple with the AccessToken field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoTokenPair) GetAccessTokenOk() (*string, bool) { + if o == nil || IsNil(o.AccessToken) { + return nil, false + } + return o.AccessToken, true +} + +// HasAccessToken returns a boolean if a field has been set. +func (o *DtoTokenPair) HasAccessToken() bool { + if o != nil && !IsNil(o.AccessToken) { + return true + } + + return false +} + +// SetAccessToken gets a reference to the given string and assigns it to the AccessToken field. +func (o *DtoTokenPair) SetAccessToken(v string) { + o.AccessToken = &v +} + +// GetExpiresIn returns the ExpiresIn field value if set, zero value otherwise. +func (o *DtoTokenPair) GetExpiresIn() int32 { + if o == nil || IsNil(o.ExpiresIn) { + var ret int32 + return ret + } + return *o.ExpiresIn +} + +// GetExpiresInOk returns a tuple with the ExpiresIn field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoTokenPair) GetExpiresInOk() (*int32, bool) { + if o == nil || IsNil(o.ExpiresIn) { + return nil, false + } + return o.ExpiresIn, true +} + +// HasExpiresIn returns a boolean if a field has been set. +func (o *DtoTokenPair) HasExpiresIn() bool { + if o != nil && !IsNil(o.ExpiresIn) { + return true + } + + return false +} + +// SetExpiresIn gets a reference to the given int32 and assigns it to the ExpiresIn field. +func (o *DtoTokenPair) SetExpiresIn(v int32) { + o.ExpiresIn = &v +} + +// GetRefreshToken returns the RefreshToken field value if set, zero value otherwise. +func (o *DtoTokenPair) GetRefreshToken() string { + if o == nil || IsNil(o.RefreshToken) { + var ret string + return ret + } + return *o.RefreshToken +} + +// GetRefreshTokenOk returns a tuple with the RefreshToken field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoTokenPair) GetRefreshTokenOk() (*string, bool) { + if o == nil || IsNil(o.RefreshToken) { + return nil, false + } + return o.RefreshToken, true +} + +// HasRefreshToken returns a boolean if a field has been set. +func (o *DtoTokenPair) HasRefreshToken() bool { + if o != nil && !IsNil(o.RefreshToken) { + return true + } + + return false +} + +// SetRefreshToken gets a reference to the given string and assigns it to the RefreshToken field. +func (o *DtoTokenPair) SetRefreshToken(v string) { + o.RefreshToken = &v +} + +// GetTokenType returns the TokenType field value if set, zero value otherwise. +func (o *DtoTokenPair) GetTokenType() string { + if o == nil || IsNil(o.TokenType) { + var ret string + return ret + } + return *o.TokenType +} + +// GetTokenTypeOk returns a tuple with the TokenType field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoTokenPair) GetTokenTypeOk() (*string, bool) { + if o == nil || IsNil(o.TokenType) { + return nil, false + } + return o.TokenType, true +} + +// HasTokenType returns a boolean if a field has been set. +func (o *DtoTokenPair) HasTokenType() bool { + if o != nil && !IsNil(o.TokenType) { + return true + } + + return false +} + +// SetTokenType gets a reference to the given string and assigns it to the TokenType field. +func (o *DtoTokenPair) SetTokenType(v string) { + o.TokenType = &v +} + +func (o DtoTokenPair) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoTokenPair) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.AccessToken) { + toSerialize["access_token"] = o.AccessToken + } + if !IsNil(o.ExpiresIn) { + toSerialize["expires_in"] = o.ExpiresIn + } + if !IsNil(o.RefreshToken) { + toSerialize["refresh_token"] = o.RefreshToken + } + if !IsNil(o.TokenType) { + toSerialize["token_type"] = o.TokenType + } + return toSerialize, nil +} + +type NullableDtoTokenPair struct { + value *DtoTokenPair + isSet bool +} + +func (v NullableDtoTokenPair) Get() *DtoTokenPair { + return v.value +} + +func (v *NullableDtoTokenPair) Set(val *DtoTokenPair) { + v.value = val + v.isSet = true +} + +func (v NullableDtoTokenPair) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoTokenPair) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoTokenPair(val *DtoTokenPair) *NullableDtoTokenPair { + return &NullableDtoTokenPair{value: val, isSet: true} +} + +func (v NullableDtoTokenPair) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoTokenPair) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_update_server_request.go b/sdk/go/model_dto_update_server_request.go new file mode 100644 index 0000000..5c13513 --- /dev/null +++ b/sdk/go/model_dto_update_server_request.go @@ -0,0 +1,340 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoUpdateServerRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoUpdateServerRequest{} + +// DtoUpdateServerRequest struct for DtoUpdateServerRequest +type DtoUpdateServerRequest struct { + Hostname *string `json:"hostname,omitempty"` + PrivateIpAddress *string `json:"private_ip_address,omitempty"` + PublicIpAddress *string `json:"public_ip_address,omitempty"` + Role *string `json:"role,omitempty"` + SshKeyId *string `json:"ssh_key_id,omitempty"` + SshUser *string `json:"ssh_user,omitempty"` + Status *string `json:"status,omitempty"` +} + +// NewDtoUpdateServerRequest instantiates a new DtoUpdateServerRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoUpdateServerRequest() *DtoUpdateServerRequest { + this := DtoUpdateServerRequest{} + return &this +} + +// NewDtoUpdateServerRequestWithDefaults instantiates a new DtoUpdateServerRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoUpdateServerRequestWithDefaults() *DtoUpdateServerRequest { + this := DtoUpdateServerRequest{} + return &this +} + +// GetHostname returns the Hostname field value if set, zero value otherwise. +func (o *DtoUpdateServerRequest) GetHostname() string { + if o == nil || IsNil(o.Hostname) { + var ret string + return ret + } + return *o.Hostname +} + +// GetHostnameOk returns a tuple with the Hostname field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateServerRequest) GetHostnameOk() (*string, bool) { + if o == nil || IsNil(o.Hostname) { + return nil, false + } + return o.Hostname, true +} + +// HasHostname returns a boolean if a field has been set. +func (o *DtoUpdateServerRequest) HasHostname() bool { + if o != nil && !IsNil(o.Hostname) { + return true + } + + return false +} + +// SetHostname gets a reference to the given string and assigns it to the Hostname field. +func (o *DtoUpdateServerRequest) SetHostname(v string) { + o.Hostname = &v +} + +// GetPrivateIpAddress returns the PrivateIpAddress field value if set, zero value otherwise. +func (o *DtoUpdateServerRequest) GetPrivateIpAddress() string { + if o == nil || IsNil(o.PrivateIpAddress) { + var ret string + return ret + } + return *o.PrivateIpAddress +} + +// GetPrivateIpAddressOk returns a tuple with the PrivateIpAddress field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateServerRequest) GetPrivateIpAddressOk() (*string, bool) { + if o == nil || IsNil(o.PrivateIpAddress) { + return nil, false + } + return o.PrivateIpAddress, true +} + +// HasPrivateIpAddress returns a boolean if a field has been set. +func (o *DtoUpdateServerRequest) HasPrivateIpAddress() bool { + if o != nil && !IsNil(o.PrivateIpAddress) { + return true + } + + return false +} + +// SetPrivateIpAddress gets a reference to the given string and assigns it to the PrivateIpAddress field. +func (o *DtoUpdateServerRequest) SetPrivateIpAddress(v string) { + o.PrivateIpAddress = &v +} + +// GetPublicIpAddress returns the PublicIpAddress field value if set, zero value otherwise. +func (o *DtoUpdateServerRequest) GetPublicIpAddress() string { + if o == nil || IsNil(o.PublicIpAddress) { + var ret string + return ret + } + return *o.PublicIpAddress +} + +// GetPublicIpAddressOk returns a tuple with the PublicIpAddress field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateServerRequest) GetPublicIpAddressOk() (*string, bool) { + if o == nil || IsNil(o.PublicIpAddress) { + return nil, false + } + return o.PublicIpAddress, true +} + +// HasPublicIpAddress returns a boolean if a field has been set. +func (o *DtoUpdateServerRequest) HasPublicIpAddress() bool { + if o != nil && !IsNil(o.PublicIpAddress) { + return true + } + + return false +} + +// SetPublicIpAddress gets a reference to the given string and assigns it to the PublicIpAddress field. +func (o *DtoUpdateServerRequest) SetPublicIpAddress(v string) { + o.PublicIpAddress = &v +} + +// GetRole returns the Role field value if set, zero value otherwise. +func (o *DtoUpdateServerRequest) GetRole() string { + if o == nil || IsNil(o.Role) { + var ret string + return ret + } + return *o.Role +} + +// GetRoleOk returns a tuple with the Role field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateServerRequest) GetRoleOk() (*string, bool) { + if o == nil || IsNil(o.Role) { + return nil, false + } + return o.Role, true +} + +// HasRole returns a boolean if a field has been set. +func (o *DtoUpdateServerRequest) HasRole() bool { + if o != nil && !IsNil(o.Role) { + return true + } + + return false +} + +// SetRole gets a reference to the given string and assigns it to the Role field. +func (o *DtoUpdateServerRequest) SetRole(v string) { + o.Role = &v +} + +// GetSshKeyId returns the SshKeyId field value if set, zero value otherwise. +func (o *DtoUpdateServerRequest) GetSshKeyId() string { + if o == nil || IsNil(o.SshKeyId) { + var ret string + return ret + } + return *o.SshKeyId +} + +// GetSshKeyIdOk returns a tuple with the SshKeyId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateServerRequest) GetSshKeyIdOk() (*string, bool) { + if o == nil || IsNil(o.SshKeyId) { + return nil, false + } + return o.SshKeyId, true +} + +// HasSshKeyId returns a boolean if a field has been set. +func (o *DtoUpdateServerRequest) HasSshKeyId() bool { + if o != nil && !IsNil(o.SshKeyId) { + return true + } + + return false +} + +// SetSshKeyId gets a reference to the given string and assigns it to the SshKeyId field. +func (o *DtoUpdateServerRequest) SetSshKeyId(v string) { + o.SshKeyId = &v +} + +// GetSshUser returns the SshUser field value if set, zero value otherwise. +func (o *DtoUpdateServerRequest) GetSshUser() string { + if o == nil || IsNil(o.SshUser) { + var ret string + return ret + } + return *o.SshUser +} + +// GetSshUserOk returns a tuple with the SshUser field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateServerRequest) GetSshUserOk() (*string, bool) { + if o == nil || IsNil(o.SshUser) { + return nil, false + } + return o.SshUser, true +} + +// HasSshUser returns a boolean if a field has been set. +func (o *DtoUpdateServerRequest) HasSshUser() bool { + if o != nil && !IsNil(o.SshUser) { + return true + } + + return false +} + +// SetSshUser gets a reference to the given string and assigns it to the SshUser field. +func (o *DtoUpdateServerRequest) SetSshUser(v string) { + o.SshUser = &v +} + +// GetStatus returns the Status field value if set, zero value otherwise. +func (o *DtoUpdateServerRequest) GetStatus() string { + if o == nil || IsNil(o.Status) { + var ret string + return ret + } + return *o.Status +} + +// GetStatusOk returns a tuple with the Status field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateServerRequest) GetStatusOk() (*string, bool) { + if o == nil || IsNil(o.Status) { + return nil, false + } + return o.Status, true +} + +// HasStatus returns a boolean if a field has been set. +func (o *DtoUpdateServerRequest) HasStatus() bool { + if o != nil && !IsNil(o.Status) { + return true + } + + return false +} + +// SetStatus gets a reference to the given string and assigns it to the Status field. +func (o *DtoUpdateServerRequest) SetStatus(v string) { + o.Status = &v +} + +func (o DtoUpdateServerRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoUpdateServerRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Hostname) { + toSerialize["hostname"] = o.Hostname + } + if !IsNil(o.PrivateIpAddress) { + toSerialize["private_ip_address"] = o.PrivateIpAddress + } + if !IsNil(o.PublicIpAddress) { + toSerialize["public_ip_address"] = o.PublicIpAddress + } + if !IsNil(o.Role) { + toSerialize["role"] = o.Role + } + if !IsNil(o.SshKeyId) { + toSerialize["ssh_key_id"] = o.SshKeyId + } + if !IsNil(o.SshUser) { + toSerialize["ssh_user"] = o.SshUser + } + if !IsNil(o.Status) { + toSerialize["status"] = o.Status + } + return toSerialize, nil +} + +type NullableDtoUpdateServerRequest struct { + value *DtoUpdateServerRequest + isSet bool +} + +func (v NullableDtoUpdateServerRequest) Get() *DtoUpdateServerRequest { + return v.value +} + +func (v *NullableDtoUpdateServerRequest) Set(val *DtoUpdateServerRequest) { + v.value = val + v.isSet = true +} + +func (v NullableDtoUpdateServerRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoUpdateServerRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoUpdateServerRequest(val *DtoUpdateServerRequest) *NullableDtoUpdateServerRequest { + return &NullableDtoUpdateServerRequest{value: val, isSet: true} +} + +func (v NullableDtoUpdateServerRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoUpdateServerRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_dto_update_taint_request.go b/sdk/go/model_dto_update_taint_request.go new file mode 100644 index 0000000..f4aa3f6 --- /dev/null +++ b/sdk/go/model_dto_update_taint_request.go @@ -0,0 +1,196 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the DtoUpdateTaintRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DtoUpdateTaintRequest{} + +// DtoUpdateTaintRequest struct for DtoUpdateTaintRequest +type DtoUpdateTaintRequest struct { + Effect *string `json:"effect,omitempty"` + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +// NewDtoUpdateTaintRequest instantiates a new DtoUpdateTaintRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDtoUpdateTaintRequest() *DtoUpdateTaintRequest { + this := DtoUpdateTaintRequest{} + return &this +} + +// NewDtoUpdateTaintRequestWithDefaults instantiates a new DtoUpdateTaintRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDtoUpdateTaintRequestWithDefaults() *DtoUpdateTaintRequest { + this := DtoUpdateTaintRequest{} + return &this +} + +// GetEffect returns the Effect field value if set, zero value otherwise. +func (o *DtoUpdateTaintRequest) GetEffect() string { + if o == nil || IsNil(o.Effect) { + var ret string + return ret + } + return *o.Effect +} + +// GetEffectOk returns a tuple with the Effect field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateTaintRequest) GetEffectOk() (*string, bool) { + if o == nil || IsNil(o.Effect) { + return nil, false + } + return o.Effect, true +} + +// HasEffect returns a boolean if a field has been set. +func (o *DtoUpdateTaintRequest) HasEffect() bool { + if o != nil && !IsNil(o.Effect) { + return true + } + + return false +} + +// SetEffect gets a reference to the given string and assigns it to the Effect field. +func (o *DtoUpdateTaintRequest) SetEffect(v string) { + o.Effect = &v +} + +// GetKey returns the Key field value if set, zero value otherwise. +func (o *DtoUpdateTaintRequest) GetKey() string { + if o == nil || IsNil(o.Key) { + var ret string + return ret + } + return *o.Key +} + +// GetKeyOk returns a tuple with the Key field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateTaintRequest) GetKeyOk() (*string, bool) { + if o == nil || IsNil(o.Key) { + return nil, false + } + return o.Key, true +} + +// HasKey returns a boolean if a field has been set. +func (o *DtoUpdateTaintRequest) HasKey() bool { + if o != nil && !IsNil(o.Key) { + return true + } + + return false +} + +// SetKey gets a reference to the given string and assigns it to the Key field. +func (o *DtoUpdateTaintRequest) SetKey(v string) { + o.Key = &v +} + +// GetValue returns the Value field value if set, zero value otherwise. +func (o *DtoUpdateTaintRequest) GetValue() string { + if o == nil || IsNil(o.Value) { + var ret string + return ret + } + return *o.Value +} + +// GetValueOk returns a tuple with the Value field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DtoUpdateTaintRequest) GetValueOk() (*string, bool) { + if o == nil || IsNil(o.Value) { + return nil, false + } + return o.Value, true +} + +// HasValue returns a boolean if a field has been set. +func (o *DtoUpdateTaintRequest) HasValue() bool { + if o != nil && !IsNil(o.Value) { + return true + } + + return false +} + +// SetValue gets a reference to the given string and assigns it to the Value field. +func (o *DtoUpdateTaintRequest) SetValue(v string) { + o.Value = &v +} + +func (o DtoUpdateTaintRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DtoUpdateTaintRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Effect) { + toSerialize["effect"] = o.Effect + } + if !IsNil(o.Key) { + toSerialize["key"] = o.Key + } + if !IsNil(o.Value) { + toSerialize["value"] = o.Value + } + return toSerialize, nil +} + +type NullableDtoUpdateTaintRequest struct { + value *DtoUpdateTaintRequest + isSet bool +} + +func (v NullableDtoUpdateTaintRequest) Get() *DtoUpdateTaintRequest { + return v.value +} + +func (v *NullableDtoUpdateTaintRequest) Set(val *DtoUpdateTaintRequest) { + v.value = val + v.isSet = true +} + +func (v NullableDtoUpdateTaintRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableDtoUpdateTaintRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDtoUpdateTaintRequest(val *DtoUpdateTaintRequest) *NullableDtoUpdateTaintRequest { + return &NullableDtoUpdateTaintRequest{value: val, isSet: true} +} + +func (v NullableDtoUpdateTaintRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDtoUpdateTaintRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_create_user_key_request.go b/sdk/go/model_handlers_create_user_key_request.go new file mode 100644 index 0000000..05d1436 --- /dev/null +++ b/sdk/go/model_handlers_create_user_key_request.go @@ -0,0 +1,161 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersCreateUserKeyRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersCreateUserKeyRequest{} + +// HandlersCreateUserKeyRequest struct for HandlersCreateUserKeyRequest +type HandlersCreateUserKeyRequest struct { + // optional TTL + ExpiresInHours *int32 `json:"expires_in_hours,omitempty"` + Name *string `json:"name,omitempty"` +} + +// NewHandlersCreateUserKeyRequest instantiates a new HandlersCreateUserKeyRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersCreateUserKeyRequest() *HandlersCreateUserKeyRequest { + this := HandlersCreateUserKeyRequest{} + return &this +} + +// NewHandlersCreateUserKeyRequestWithDefaults instantiates a new HandlersCreateUserKeyRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersCreateUserKeyRequestWithDefaults() *HandlersCreateUserKeyRequest { + this := HandlersCreateUserKeyRequest{} + return &this +} + +// GetExpiresInHours returns the ExpiresInHours field value if set, zero value otherwise. +func (o *HandlersCreateUserKeyRequest) GetExpiresInHours() int32 { + if o == nil || IsNil(o.ExpiresInHours) { + var ret int32 + return ret + } + return *o.ExpiresInHours +} + +// GetExpiresInHoursOk returns a tuple with the ExpiresInHours field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersCreateUserKeyRequest) GetExpiresInHoursOk() (*int32, bool) { + if o == nil || IsNil(o.ExpiresInHours) { + return nil, false + } + return o.ExpiresInHours, true +} + +// HasExpiresInHours returns a boolean if a field has been set. +func (o *HandlersCreateUserKeyRequest) HasExpiresInHours() bool { + if o != nil && !IsNil(o.ExpiresInHours) { + return true + } + + return false +} + +// SetExpiresInHours gets a reference to the given int32 and assigns it to the ExpiresInHours field. +func (o *HandlersCreateUserKeyRequest) SetExpiresInHours(v int32) { + o.ExpiresInHours = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *HandlersCreateUserKeyRequest) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersCreateUserKeyRequest) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *HandlersCreateUserKeyRequest) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *HandlersCreateUserKeyRequest) SetName(v string) { + o.Name = &v +} + +func (o HandlersCreateUserKeyRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersCreateUserKeyRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.ExpiresInHours) { + toSerialize["expires_in_hours"] = o.ExpiresInHours + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableHandlersCreateUserKeyRequest struct { + value *HandlersCreateUserKeyRequest + isSet bool +} + +func (v NullableHandlersCreateUserKeyRequest) Get() *HandlersCreateUserKeyRequest { + return v.value +} + +func (v *NullableHandlersCreateUserKeyRequest) Set(val *HandlersCreateUserKeyRequest) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersCreateUserKeyRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersCreateUserKeyRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersCreateUserKeyRequest(val *HandlersCreateUserKeyRequest) *NullableHandlersCreateUserKeyRequest { + return &NullableHandlersCreateUserKeyRequest{value: val, isSet: true} +} + +func (v NullableHandlersCreateUserKeyRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersCreateUserKeyRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_me_response.go b/sdk/go/model_handlers_me_response.go new file mode 100644 index 0000000..8eaca86 --- /dev/null +++ b/sdk/go/model_handlers_me_response.go @@ -0,0 +1,414 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" + "time" +) + +// checks if the HandlersMeResponse type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersMeResponse{} + +// HandlersMeResponse struct for HandlersMeResponse +type HandlersMeResponse struct { + AvatarUrl *string `json:"avatar_url,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Emails []ModelsUserEmail `json:"emails,omitempty"` + // example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + Id *string `json:"id,omitempty"` + IsDisabled *bool `json:"is_disabled,omitempty"` + Organizations []ModelsOrganization `json:"organizations,omitempty"` + PrimaryEmail *string `json:"primary_email,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// NewHandlersMeResponse instantiates a new HandlersMeResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersMeResponse() *HandlersMeResponse { + this := HandlersMeResponse{} + return &this +} + +// NewHandlersMeResponseWithDefaults instantiates a new HandlersMeResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersMeResponseWithDefaults() *HandlersMeResponse { + this := HandlersMeResponse{} + return &this +} + +// GetAvatarUrl returns the AvatarUrl field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetAvatarUrl() string { + if o == nil || IsNil(o.AvatarUrl) { + var ret string + return ret + } + return *o.AvatarUrl +} + +// GetAvatarUrlOk returns a tuple with the AvatarUrl field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetAvatarUrlOk() (*string, bool) { + if o == nil || IsNil(o.AvatarUrl) { + return nil, false + } + return o.AvatarUrl, true +} + +// HasAvatarUrl returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasAvatarUrl() bool { + if o != nil && !IsNil(o.AvatarUrl) { + return true + } + + return false +} + +// SetAvatarUrl gets a reference to the given string and assigns it to the AvatarUrl field. +func (o *HandlersMeResponse) SetAvatarUrl(v string) { + o.AvatarUrl = &v +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetCreatedAt() time.Time { + if o == nil || IsNil(o.CreatedAt) { + var ret time.Time + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetCreatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given time.Time and assigns it to the CreatedAt field. +func (o *HandlersMeResponse) SetCreatedAt(v time.Time) { + o.CreatedAt = &v +} + +// GetDisplayName returns the DisplayName field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetDisplayName() string { + if o == nil || IsNil(o.DisplayName) { + var ret string + return ret + } + return *o.DisplayName +} + +// GetDisplayNameOk returns a tuple with the DisplayName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetDisplayNameOk() (*string, bool) { + if o == nil || IsNil(o.DisplayName) { + return nil, false + } + return o.DisplayName, true +} + +// HasDisplayName returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasDisplayName() bool { + if o != nil && !IsNil(o.DisplayName) { + return true + } + + return false +} + +// SetDisplayName gets a reference to the given string and assigns it to the DisplayName field. +func (o *HandlersMeResponse) SetDisplayName(v string) { + o.DisplayName = &v +} + +// GetEmails returns the Emails field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetEmails() []ModelsUserEmail { + if o == nil || IsNil(o.Emails) { + var ret []ModelsUserEmail + return ret + } + return o.Emails +} + +// GetEmailsOk returns a tuple with the Emails field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetEmailsOk() ([]ModelsUserEmail, bool) { + if o == nil || IsNil(o.Emails) { + return nil, false + } + return o.Emails, true +} + +// HasEmails returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasEmails() bool { + if o != nil && !IsNil(o.Emails) { + return true + } + + return false +} + +// SetEmails gets a reference to the given []ModelsUserEmail and assigns it to the Emails field. +func (o *HandlersMeResponse) SetEmails(v []ModelsUserEmail) { + o.Emails = v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *HandlersMeResponse) SetId(v string) { + o.Id = &v +} + +// GetIsDisabled returns the IsDisabled field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetIsDisabled() bool { + if o == nil || IsNil(o.IsDisabled) { + var ret bool + return ret + } + return *o.IsDisabled +} + +// GetIsDisabledOk returns a tuple with the IsDisabled field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetIsDisabledOk() (*bool, bool) { + if o == nil || IsNil(o.IsDisabled) { + return nil, false + } + return o.IsDisabled, true +} + +// HasIsDisabled returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasIsDisabled() bool { + if o != nil && !IsNil(o.IsDisabled) { + return true + } + + return false +} + +// SetIsDisabled gets a reference to the given bool and assigns it to the IsDisabled field. +func (o *HandlersMeResponse) SetIsDisabled(v bool) { + o.IsDisabled = &v +} + +// GetOrganizations returns the Organizations field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetOrganizations() []ModelsOrganization { + if o == nil || IsNil(o.Organizations) { + var ret []ModelsOrganization + return ret + } + return o.Organizations +} + +// GetOrganizationsOk returns a tuple with the Organizations field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetOrganizationsOk() ([]ModelsOrganization, bool) { + if o == nil || IsNil(o.Organizations) { + return nil, false + } + return o.Organizations, true +} + +// HasOrganizations returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasOrganizations() bool { + if o != nil && !IsNil(o.Organizations) { + return true + } + + return false +} + +// SetOrganizations gets a reference to the given []ModelsOrganization and assigns it to the Organizations field. +func (o *HandlersMeResponse) SetOrganizations(v []ModelsOrganization) { + o.Organizations = v +} + +// GetPrimaryEmail returns the PrimaryEmail field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetPrimaryEmail() string { + if o == nil || IsNil(o.PrimaryEmail) { + var ret string + return ret + } + return *o.PrimaryEmail +} + +// GetPrimaryEmailOk returns a tuple with the PrimaryEmail field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetPrimaryEmailOk() (*string, bool) { + if o == nil || IsNil(o.PrimaryEmail) { + return nil, false + } + return o.PrimaryEmail, true +} + +// HasPrimaryEmail returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasPrimaryEmail() bool { + if o != nil && !IsNil(o.PrimaryEmail) { + return true + } + + return false +} + +// SetPrimaryEmail gets a reference to the given string and assigns it to the PrimaryEmail field. +func (o *HandlersMeResponse) SetPrimaryEmail(v string) { + o.PrimaryEmail = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *HandlersMeResponse) GetUpdatedAt() time.Time { + if o == nil || IsNil(o.UpdatedAt) { + var ret time.Time + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMeResponse) GetUpdatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *HandlersMeResponse) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given time.Time and assigns it to the UpdatedAt field. +func (o *HandlersMeResponse) SetUpdatedAt(v time.Time) { + o.UpdatedAt = &v +} + +func (o HandlersMeResponse) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersMeResponse) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.AvatarUrl) { + toSerialize["avatar_url"] = o.AvatarUrl + } + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.DisplayName) { + toSerialize["display_name"] = o.DisplayName + } + if !IsNil(o.Emails) { + toSerialize["emails"] = o.Emails + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.IsDisabled) { + toSerialize["is_disabled"] = o.IsDisabled + } + if !IsNil(o.Organizations) { + toSerialize["organizations"] = o.Organizations + } + if !IsNil(o.PrimaryEmail) { + toSerialize["primary_email"] = o.PrimaryEmail + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + return toSerialize, nil +} + +type NullableHandlersMeResponse struct { + value *HandlersMeResponse + isSet bool +} + +func (v NullableHandlersMeResponse) Get() *HandlersMeResponse { + return v.value +} + +func (v *NullableHandlersMeResponse) Set(val *HandlersMeResponse) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersMeResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersMeResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersMeResponse(val *HandlersMeResponse) *NullableHandlersMeResponse { + return &NullableHandlersMeResponse{value: val, isSet: true} +} + +func (v NullableHandlersMeResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersMeResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_member_out.go b/sdk/go/model_handlers_member_out.go new file mode 100644 index 0000000..d49d09c --- /dev/null +++ b/sdk/go/model_handlers_member_out.go @@ -0,0 +1,197 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersMemberOut type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersMemberOut{} + +// HandlersMemberOut struct for HandlersMemberOut +type HandlersMemberOut struct { + Email *string `json:"email,omitempty"` + // owner/admin/member + Role *string `json:"role,omitempty"` + UserId *string `json:"user_id,omitempty"` +} + +// NewHandlersMemberOut instantiates a new HandlersMemberOut object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersMemberOut() *HandlersMemberOut { + this := HandlersMemberOut{} + return &this +} + +// NewHandlersMemberOutWithDefaults instantiates a new HandlersMemberOut object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersMemberOutWithDefaults() *HandlersMemberOut { + this := HandlersMemberOut{} + return &this +} + +// GetEmail returns the Email field value if set, zero value otherwise. +func (o *HandlersMemberOut) GetEmail() string { + if o == nil || IsNil(o.Email) { + var ret string + return ret + } + return *o.Email +} + +// GetEmailOk returns a tuple with the Email field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMemberOut) GetEmailOk() (*string, bool) { + if o == nil || IsNil(o.Email) { + return nil, false + } + return o.Email, true +} + +// HasEmail returns a boolean if a field has been set. +func (o *HandlersMemberOut) HasEmail() bool { + if o != nil && !IsNil(o.Email) { + return true + } + + return false +} + +// SetEmail gets a reference to the given string and assigns it to the Email field. +func (o *HandlersMemberOut) SetEmail(v string) { + o.Email = &v +} + +// GetRole returns the Role field value if set, zero value otherwise. +func (o *HandlersMemberOut) GetRole() string { + if o == nil || IsNil(o.Role) { + var ret string + return ret + } + return *o.Role +} + +// GetRoleOk returns a tuple with the Role field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMemberOut) GetRoleOk() (*string, bool) { + if o == nil || IsNil(o.Role) { + return nil, false + } + return o.Role, true +} + +// HasRole returns a boolean if a field has been set. +func (o *HandlersMemberOut) HasRole() bool { + if o != nil && !IsNil(o.Role) { + return true + } + + return false +} + +// SetRole gets a reference to the given string and assigns it to the Role field. +func (o *HandlersMemberOut) SetRole(v string) { + o.Role = &v +} + +// GetUserId returns the UserId field value if set, zero value otherwise. +func (o *HandlersMemberOut) GetUserId() string { + if o == nil || IsNil(o.UserId) { + var ret string + return ret + } + return *o.UserId +} + +// GetUserIdOk returns a tuple with the UserId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMemberOut) GetUserIdOk() (*string, bool) { + if o == nil || IsNil(o.UserId) { + return nil, false + } + return o.UserId, true +} + +// HasUserId returns a boolean if a field has been set. +func (o *HandlersMemberOut) HasUserId() bool { + if o != nil && !IsNil(o.UserId) { + return true + } + + return false +} + +// SetUserId gets a reference to the given string and assigns it to the UserId field. +func (o *HandlersMemberOut) SetUserId(v string) { + o.UserId = &v +} + +func (o HandlersMemberOut) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersMemberOut) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Email) { + toSerialize["email"] = o.Email + } + if !IsNil(o.Role) { + toSerialize["role"] = o.Role + } + if !IsNil(o.UserId) { + toSerialize["user_id"] = o.UserId + } + return toSerialize, nil +} + +type NullableHandlersMemberOut struct { + value *HandlersMemberOut + isSet bool +} + +func (v NullableHandlersMemberOut) Get() *HandlersMemberOut { + return v.value +} + +func (v *NullableHandlersMemberOut) Set(val *HandlersMemberOut) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersMemberOut) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersMemberOut) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersMemberOut(val *HandlersMemberOut) *NullableHandlersMemberOut { + return &NullableHandlersMemberOut{value: val, isSet: true} +} + +func (v NullableHandlersMemberOut) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersMemberOut) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_member_upsert_req.go b/sdk/go/model_handlers_member_upsert_req.go new file mode 100644 index 0000000..657ad97 --- /dev/null +++ b/sdk/go/model_handlers_member_upsert_req.go @@ -0,0 +1,160 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersMemberUpsertReq type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersMemberUpsertReq{} + +// HandlersMemberUpsertReq struct for HandlersMemberUpsertReq +type HandlersMemberUpsertReq struct { + Role *string `json:"role,omitempty"` + UserId *string `json:"user_id,omitempty"` +} + +// NewHandlersMemberUpsertReq instantiates a new HandlersMemberUpsertReq object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersMemberUpsertReq() *HandlersMemberUpsertReq { + this := HandlersMemberUpsertReq{} + return &this +} + +// NewHandlersMemberUpsertReqWithDefaults instantiates a new HandlersMemberUpsertReq object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersMemberUpsertReqWithDefaults() *HandlersMemberUpsertReq { + this := HandlersMemberUpsertReq{} + return &this +} + +// GetRole returns the Role field value if set, zero value otherwise. +func (o *HandlersMemberUpsertReq) GetRole() string { + if o == nil || IsNil(o.Role) { + var ret string + return ret + } + return *o.Role +} + +// GetRoleOk returns a tuple with the Role field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMemberUpsertReq) GetRoleOk() (*string, bool) { + if o == nil || IsNil(o.Role) { + return nil, false + } + return o.Role, true +} + +// HasRole returns a boolean if a field has been set. +func (o *HandlersMemberUpsertReq) HasRole() bool { + if o != nil && !IsNil(o.Role) { + return true + } + + return false +} + +// SetRole gets a reference to the given string and assigns it to the Role field. +func (o *HandlersMemberUpsertReq) SetRole(v string) { + o.Role = &v +} + +// GetUserId returns the UserId field value if set, zero value otherwise. +func (o *HandlersMemberUpsertReq) GetUserId() string { + if o == nil || IsNil(o.UserId) { + var ret string + return ret + } + return *o.UserId +} + +// GetUserIdOk returns a tuple with the UserId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersMemberUpsertReq) GetUserIdOk() (*string, bool) { + if o == nil || IsNil(o.UserId) { + return nil, false + } + return o.UserId, true +} + +// HasUserId returns a boolean if a field has been set. +func (o *HandlersMemberUpsertReq) HasUserId() bool { + if o != nil && !IsNil(o.UserId) { + return true + } + + return false +} + +// SetUserId gets a reference to the given string and assigns it to the UserId field. +func (o *HandlersMemberUpsertReq) SetUserId(v string) { + o.UserId = &v +} + +func (o HandlersMemberUpsertReq) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersMemberUpsertReq) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Role) { + toSerialize["role"] = o.Role + } + if !IsNil(o.UserId) { + toSerialize["user_id"] = o.UserId + } + return toSerialize, nil +} + +type NullableHandlersMemberUpsertReq struct { + value *HandlersMemberUpsertReq + isSet bool +} + +func (v NullableHandlersMemberUpsertReq) Get() *HandlersMemberUpsertReq { + return v.value +} + +func (v *NullableHandlersMemberUpsertReq) Set(val *HandlersMemberUpsertReq) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersMemberUpsertReq) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersMemberUpsertReq) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersMemberUpsertReq(val *HandlersMemberUpsertReq) *NullableHandlersMemberUpsertReq { + return &NullableHandlersMemberUpsertReq{value: val, isSet: true} +} + +func (v NullableHandlersMemberUpsertReq) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersMemberUpsertReq) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_org_create_req.go b/sdk/go/model_handlers_org_create_req.go new file mode 100644 index 0000000..7243fbf --- /dev/null +++ b/sdk/go/model_handlers_org_create_req.go @@ -0,0 +1,160 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersOrgCreateReq type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersOrgCreateReq{} + +// HandlersOrgCreateReq struct for HandlersOrgCreateReq +type HandlersOrgCreateReq struct { + Domain *string `json:"domain,omitempty"` + Name *string `json:"name,omitempty"` +} + +// NewHandlersOrgCreateReq instantiates a new HandlersOrgCreateReq object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersOrgCreateReq() *HandlersOrgCreateReq { + this := HandlersOrgCreateReq{} + return &this +} + +// NewHandlersOrgCreateReqWithDefaults instantiates a new HandlersOrgCreateReq object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersOrgCreateReqWithDefaults() *HandlersOrgCreateReq { + this := HandlersOrgCreateReq{} + return &this +} + +// GetDomain returns the Domain field value if set, zero value otherwise. +func (o *HandlersOrgCreateReq) GetDomain() string { + if o == nil || IsNil(o.Domain) { + var ret string + return ret + } + return *o.Domain +} + +// GetDomainOk returns a tuple with the Domain field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgCreateReq) GetDomainOk() (*string, bool) { + if o == nil || IsNil(o.Domain) { + return nil, false + } + return o.Domain, true +} + +// HasDomain returns a boolean if a field has been set. +func (o *HandlersOrgCreateReq) HasDomain() bool { + if o != nil && !IsNil(o.Domain) { + return true + } + + return false +} + +// SetDomain gets a reference to the given string and assigns it to the Domain field. +func (o *HandlersOrgCreateReq) SetDomain(v string) { + o.Domain = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *HandlersOrgCreateReq) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgCreateReq) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *HandlersOrgCreateReq) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *HandlersOrgCreateReq) SetName(v string) { + o.Name = &v +} + +func (o HandlersOrgCreateReq) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersOrgCreateReq) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Domain) { + toSerialize["domain"] = o.Domain + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableHandlersOrgCreateReq struct { + value *HandlersOrgCreateReq + isSet bool +} + +func (v NullableHandlersOrgCreateReq) Get() *HandlersOrgCreateReq { + return v.value +} + +func (v *NullableHandlersOrgCreateReq) Set(val *HandlersOrgCreateReq) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersOrgCreateReq) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersOrgCreateReq) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersOrgCreateReq(val *HandlersOrgCreateReq) *NullableHandlersOrgCreateReq { + return &NullableHandlersOrgCreateReq{value: val, isSet: true} +} + +func (v NullableHandlersOrgCreateReq) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersOrgCreateReq) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_org_key_create_req.go b/sdk/go/model_handlers_org_key_create_req.go new file mode 100644 index 0000000..e62646f --- /dev/null +++ b/sdk/go/model_handlers_org_key_create_req.go @@ -0,0 +1,160 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersOrgKeyCreateReq type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersOrgKeyCreateReq{} + +// HandlersOrgKeyCreateReq struct for HandlersOrgKeyCreateReq +type HandlersOrgKeyCreateReq struct { + ExpiresInHours *int32 `json:"expires_in_hours,omitempty"` + Name *string `json:"name,omitempty"` +} + +// NewHandlersOrgKeyCreateReq instantiates a new HandlersOrgKeyCreateReq object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersOrgKeyCreateReq() *HandlersOrgKeyCreateReq { + this := HandlersOrgKeyCreateReq{} + return &this +} + +// NewHandlersOrgKeyCreateReqWithDefaults instantiates a new HandlersOrgKeyCreateReq object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersOrgKeyCreateReqWithDefaults() *HandlersOrgKeyCreateReq { + this := HandlersOrgKeyCreateReq{} + return &this +} + +// GetExpiresInHours returns the ExpiresInHours field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateReq) GetExpiresInHours() int32 { + if o == nil || IsNil(o.ExpiresInHours) { + var ret int32 + return ret + } + return *o.ExpiresInHours +} + +// GetExpiresInHoursOk returns a tuple with the ExpiresInHours field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateReq) GetExpiresInHoursOk() (*int32, bool) { + if o == nil || IsNil(o.ExpiresInHours) { + return nil, false + } + return o.ExpiresInHours, true +} + +// HasExpiresInHours returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateReq) HasExpiresInHours() bool { + if o != nil && !IsNil(o.ExpiresInHours) { + return true + } + + return false +} + +// SetExpiresInHours gets a reference to the given int32 and assigns it to the ExpiresInHours field. +func (o *HandlersOrgKeyCreateReq) SetExpiresInHours(v int32) { + o.ExpiresInHours = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateReq) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateReq) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateReq) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *HandlersOrgKeyCreateReq) SetName(v string) { + o.Name = &v +} + +func (o HandlersOrgKeyCreateReq) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersOrgKeyCreateReq) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.ExpiresInHours) { + toSerialize["expires_in_hours"] = o.ExpiresInHours + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableHandlersOrgKeyCreateReq struct { + value *HandlersOrgKeyCreateReq + isSet bool +} + +func (v NullableHandlersOrgKeyCreateReq) Get() *HandlersOrgKeyCreateReq { + return v.value +} + +func (v *NullableHandlersOrgKeyCreateReq) Set(val *HandlersOrgKeyCreateReq) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersOrgKeyCreateReq) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersOrgKeyCreateReq) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersOrgKeyCreateReq(val *HandlersOrgKeyCreateReq) *NullableHandlersOrgKeyCreateReq { + return &NullableHandlersOrgKeyCreateReq{value: val, isSet: true} +} + +func (v NullableHandlersOrgKeyCreateReq) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersOrgKeyCreateReq) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_org_key_create_resp.go b/sdk/go/model_handlers_org_key_create_resp.go new file mode 100644 index 0000000..68209dc --- /dev/null +++ b/sdk/go/model_handlers_org_key_create_resp.go @@ -0,0 +1,343 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersOrgKeyCreateResp type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersOrgKeyCreateResp{} + +// HandlersOrgKeyCreateResp struct for HandlersOrgKeyCreateResp +type HandlersOrgKeyCreateResp struct { + CreatedAt *string `json:"created_at,omitempty"` + ExpiresAt *string `json:"expires_at,omitempty"` + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + // shown once: + OrgKey *string `json:"org_key,omitempty"` + // shown once: + OrgSecret *string `json:"org_secret,omitempty"` + // \"org\" + Scope *string `json:"scope,omitempty"` +} + +// NewHandlersOrgKeyCreateResp instantiates a new HandlersOrgKeyCreateResp object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersOrgKeyCreateResp() *HandlersOrgKeyCreateResp { + this := HandlersOrgKeyCreateResp{} + return &this +} + +// NewHandlersOrgKeyCreateRespWithDefaults instantiates a new HandlersOrgKeyCreateResp object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersOrgKeyCreateRespWithDefaults() *HandlersOrgKeyCreateResp { + this := HandlersOrgKeyCreateResp{} + return &this +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateResp) GetCreatedAt() string { + if o == nil || IsNil(o.CreatedAt) { + var ret string + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateResp) GetCreatedAtOk() (*string, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateResp) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given string and assigns it to the CreatedAt field. +func (o *HandlersOrgKeyCreateResp) SetCreatedAt(v string) { + o.CreatedAt = &v +} + +// GetExpiresAt returns the ExpiresAt field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateResp) GetExpiresAt() string { + if o == nil || IsNil(o.ExpiresAt) { + var ret string + return ret + } + return *o.ExpiresAt +} + +// GetExpiresAtOk returns a tuple with the ExpiresAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateResp) GetExpiresAtOk() (*string, bool) { + if o == nil || IsNil(o.ExpiresAt) { + return nil, false + } + return o.ExpiresAt, true +} + +// HasExpiresAt returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateResp) HasExpiresAt() bool { + if o != nil && !IsNil(o.ExpiresAt) { + return true + } + + return false +} + +// SetExpiresAt gets a reference to the given string and assigns it to the ExpiresAt field. +func (o *HandlersOrgKeyCreateResp) SetExpiresAt(v string) { + o.ExpiresAt = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateResp) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateResp) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateResp) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *HandlersOrgKeyCreateResp) SetId(v string) { + o.Id = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateResp) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateResp) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateResp) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *HandlersOrgKeyCreateResp) SetName(v string) { + o.Name = &v +} + +// GetOrgKey returns the OrgKey field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateResp) GetOrgKey() string { + if o == nil || IsNil(o.OrgKey) { + var ret string + return ret + } + return *o.OrgKey +} + +// GetOrgKeyOk returns a tuple with the OrgKey field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateResp) GetOrgKeyOk() (*string, bool) { + if o == nil || IsNil(o.OrgKey) { + return nil, false + } + return o.OrgKey, true +} + +// HasOrgKey returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateResp) HasOrgKey() bool { + if o != nil && !IsNil(o.OrgKey) { + return true + } + + return false +} + +// SetOrgKey gets a reference to the given string and assigns it to the OrgKey field. +func (o *HandlersOrgKeyCreateResp) SetOrgKey(v string) { + o.OrgKey = &v +} + +// GetOrgSecret returns the OrgSecret field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateResp) GetOrgSecret() string { + if o == nil || IsNil(o.OrgSecret) { + var ret string + return ret + } + return *o.OrgSecret +} + +// GetOrgSecretOk returns a tuple with the OrgSecret field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateResp) GetOrgSecretOk() (*string, bool) { + if o == nil || IsNil(o.OrgSecret) { + return nil, false + } + return o.OrgSecret, true +} + +// HasOrgSecret returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateResp) HasOrgSecret() bool { + if o != nil && !IsNil(o.OrgSecret) { + return true + } + + return false +} + +// SetOrgSecret gets a reference to the given string and assigns it to the OrgSecret field. +func (o *HandlersOrgKeyCreateResp) SetOrgSecret(v string) { + o.OrgSecret = &v +} + +// GetScope returns the Scope field value if set, zero value otherwise. +func (o *HandlersOrgKeyCreateResp) GetScope() string { + if o == nil || IsNil(o.Scope) { + var ret string + return ret + } + return *o.Scope +} + +// GetScopeOk returns a tuple with the Scope field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgKeyCreateResp) GetScopeOk() (*string, bool) { + if o == nil || IsNil(o.Scope) { + return nil, false + } + return o.Scope, true +} + +// HasScope returns a boolean if a field has been set. +func (o *HandlersOrgKeyCreateResp) HasScope() bool { + if o != nil && !IsNil(o.Scope) { + return true + } + + return false +} + +// SetScope gets a reference to the given string and assigns it to the Scope field. +func (o *HandlersOrgKeyCreateResp) SetScope(v string) { + o.Scope = &v +} + +func (o HandlersOrgKeyCreateResp) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersOrgKeyCreateResp) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.ExpiresAt) { + toSerialize["expires_at"] = o.ExpiresAt + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.OrgKey) { + toSerialize["org_key"] = o.OrgKey + } + if !IsNil(o.OrgSecret) { + toSerialize["org_secret"] = o.OrgSecret + } + if !IsNil(o.Scope) { + toSerialize["scope"] = o.Scope + } + return toSerialize, nil +} + +type NullableHandlersOrgKeyCreateResp struct { + value *HandlersOrgKeyCreateResp + isSet bool +} + +func (v NullableHandlersOrgKeyCreateResp) Get() *HandlersOrgKeyCreateResp { + return v.value +} + +func (v *NullableHandlersOrgKeyCreateResp) Set(val *HandlersOrgKeyCreateResp) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersOrgKeyCreateResp) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersOrgKeyCreateResp) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersOrgKeyCreateResp(val *HandlersOrgKeyCreateResp) *NullableHandlersOrgKeyCreateResp { + return &NullableHandlersOrgKeyCreateResp{value: val, isSet: true} +} + +func (v NullableHandlersOrgKeyCreateResp) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersOrgKeyCreateResp) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_org_update_req.go b/sdk/go/model_handlers_org_update_req.go new file mode 100644 index 0000000..a6ad403 --- /dev/null +++ b/sdk/go/model_handlers_org_update_req.go @@ -0,0 +1,160 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersOrgUpdateReq type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersOrgUpdateReq{} + +// HandlersOrgUpdateReq struct for HandlersOrgUpdateReq +type HandlersOrgUpdateReq struct { + Domain *string `json:"domain,omitempty"` + Name *string `json:"name,omitempty"` +} + +// NewHandlersOrgUpdateReq instantiates a new HandlersOrgUpdateReq object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersOrgUpdateReq() *HandlersOrgUpdateReq { + this := HandlersOrgUpdateReq{} + return &this +} + +// NewHandlersOrgUpdateReqWithDefaults instantiates a new HandlersOrgUpdateReq object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersOrgUpdateReqWithDefaults() *HandlersOrgUpdateReq { + this := HandlersOrgUpdateReq{} + return &this +} + +// GetDomain returns the Domain field value if set, zero value otherwise. +func (o *HandlersOrgUpdateReq) GetDomain() string { + if o == nil || IsNil(o.Domain) { + var ret string + return ret + } + return *o.Domain +} + +// GetDomainOk returns a tuple with the Domain field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgUpdateReq) GetDomainOk() (*string, bool) { + if o == nil || IsNil(o.Domain) { + return nil, false + } + return o.Domain, true +} + +// HasDomain returns a boolean if a field has been set. +func (o *HandlersOrgUpdateReq) HasDomain() bool { + if o != nil && !IsNil(o.Domain) { + return true + } + + return false +} + +// SetDomain gets a reference to the given string and assigns it to the Domain field. +func (o *HandlersOrgUpdateReq) SetDomain(v string) { + o.Domain = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *HandlersOrgUpdateReq) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersOrgUpdateReq) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *HandlersOrgUpdateReq) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *HandlersOrgUpdateReq) SetName(v string) { + o.Name = &v +} + +func (o HandlersOrgUpdateReq) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersOrgUpdateReq) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Domain) { + toSerialize["domain"] = o.Domain + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableHandlersOrgUpdateReq struct { + value *HandlersOrgUpdateReq + isSet bool +} + +func (v NullableHandlersOrgUpdateReq) Get() *HandlersOrgUpdateReq { + return v.value +} + +func (v *NullableHandlersOrgUpdateReq) Set(val *HandlersOrgUpdateReq) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersOrgUpdateReq) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersOrgUpdateReq) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersOrgUpdateReq(val *HandlersOrgUpdateReq) *NullableHandlersOrgUpdateReq { + return &NullableHandlersOrgUpdateReq{value: val, isSet: true} +} + +func (v NullableHandlersOrgUpdateReq) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersOrgUpdateReq) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_update_me_request.go b/sdk/go/model_handlers_update_me_request.go new file mode 100644 index 0000000..79b57fc --- /dev/null +++ b/sdk/go/model_handlers_update_me_request.go @@ -0,0 +1,124 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersUpdateMeRequest type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersUpdateMeRequest{} + +// HandlersUpdateMeRequest struct for HandlersUpdateMeRequest +type HandlersUpdateMeRequest struct { + DisplayName *string `json:"display_name,omitempty"` +} + +// NewHandlersUpdateMeRequest instantiates a new HandlersUpdateMeRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersUpdateMeRequest() *HandlersUpdateMeRequest { + this := HandlersUpdateMeRequest{} + return &this +} + +// NewHandlersUpdateMeRequestWithDefaults instantiates a new HandlersUpdateMeRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersUpdateMeRequestWithDefaults() *HandlersUpdateMeRequest { + this := HandlersUpdateMeRequest{} + return &this +} + +// GetDisplayName returns the DisplayName field value if set, zero value otherwise. +func (o *HandlersUpdateMeRequest) GetDisplayName() string { + if o == nil || IsNil(o.DisplayName) { + var ret string + return ret + } + return *o.DisplayName +} + +// GetDisplayNameOk returns a tuple with the DisplayName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersUpdateMeRequest) GetDisplayNameOk() (*string, bool) { + if o == nil || IsNil(o.DisplayName) { + return nil, false + } + return o.DisplayName, true +} + +// HasDisplayName returns a boolean if a field has been set. +func (o *HandlersUpdateMeRequest) HasDisplayName() bool { + if o != nil && !IsNil(o.DisplayName) { + return true + } + + return false +} + +// SetDisplayName gets a reference to the given string and assigns it to the DisplayName field. +func (o *HandlersUpdateMeRequest) SetDisplayName(v string) { + o.DisplayName = &v +} + +func (o HandlersUpdateMeRequest) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersUpdateMeRequest) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.DisplayName) { + toSerialize["display_name"] = o.DisplayName + } + return toSerialize, nil +} + +type NullableHandlersUpdateMeRequest struct { + value *HandlersUpdateMeRequest + isSet bool +} + +func (v NullableHandlersUpdateMeRequest) Get() *HandlersUpdateMeRequest { + return v.value +} + +func (v *NullableHandlersUpdateMeRequest) Set(val *HandlersUpdateMeRequest) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersUpdateMeRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersUpdateMeRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersUpdateMeRequest(val *HandlersUpdateMeRequest) *NullableHandlersUpdateMeRequest { + return &NullableHandlersUpdateMeRequest{value: val, isSet: true} +} + +func (v NullableHandlersUpdateMeRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersUpdateMeRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_handlers_user_api_key_out.go b/sdk/go/model_handlers_user_api_key_out.go new file mode 100644 index 0000000..f3b4bd7 --- /dev/null +++ b/sdk/go/model_handlers_user_api_key_out.go @@ -0,0 +1,342 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the HandlersUserAPIKeyOut type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HandlersUserAPIKeyOut{} + +// HandlersUserAPIKeyOut struct for HandlersUserAPIKeyOut +type HandlersUserAPIKeyOut struct { + CreatedAt *string `json:"created_at,omitempty"` + ExpiresAt *string `json:"expires_at,omitempty"` + Id *string `json:"id,omitempty"` + LastUsedAt *string `json:"last_used_at,omitempty"` + Name *string `json:"name,omitempty"` + // Shown only on create: + Plain *string `json:"plain,omitempty"` + // \"user\" + Scope *string `json:"scope,omitempty"` +} + +// NewHandlersUserAPIKeyOut instantiates a new HandlersUserAPIKeyOut object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHandlersUserAPIKeyOut() *HandlersUserAPIKeyOut { + this := HandlersUserAPIKeyOut{} + return &this +} + +// NewHandlersUserAPIKeyOutWithDefaults instantiates a new HandlersUserAPIKeyOut object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHandlersUserAPIKeyOutWithDefaults() *HandlersUserAPIKeyOut { + this := HandlersUserAPIKeyOut{} + return &this +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *HandlersUserAPIKeyOut) GetCreatedAt() string { + if o == nil || IsNil(o.CreatedAt) { + var ret string + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersUserAPIKeyOut) GetCreatedAtOk() (*string, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *HandlersUserAPIKeyOut) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given string and assigns it to the CreatedAt field. +func (o *HandlersUserAPIKeyOut) SetCreatedAt(v string) { + o.CreatedAt = &v +} + +// GetExpiresAt returns the ExpiresAt field value if set, zero value otherwise. +func (o *HandlersUserAPIKeyOut) GetExpiresAt() string { + if o == nil || IsNil(o.ExpiresAt) { + var ret string + return ret + } + return *o.ExpiresAt +} + +// GetExpiresAtOk returns a tuple with the ExpiresAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersUserAPIKeyOut) GetExpiresAtOk() (*string, bool) { + if o == nil || IsNil(o.ExpiresAt) { + return nil, false + } + return o.ExpiresAt, true +} + +// HasExpiresAt returns a boolean if a field has been set. +func (o *HandlersUserAPIKeyOut) HasExpiresAt() bool { + if o != nil && !IsNil(o.ExpiresAt) { + return true + } + + return false +} + +// SetExpiresAt gets a reference to the given string and assigns it to the ExpiresAt field. +func (o *HandlersUserAPIKeyOut) SetExpiresAt(v string) { + o.ExpiresAt = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *HandlersUserAPIKeyOut) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersUserAPIKeyOut) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *HandlersUserAPIKeyOut) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *HandlersUserAPIKeyOut) SetId(v string) { + o.Id = &v +} + +// GetLastUsedAt returns the LastUsedAt field value if set, zero value otherwise. +func (o *HandlersUserAPIKeyOut) GetLastUsedAt() string { + if o == nil || IsNil(o.LastUsedAt) { + var ret string + return ret + } + return *o.LastUsedAt +} + +// GetLastUsedAtOk returns a tuple with the LastUsedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersUserAPIKeyOut) GetLastUsedAtOk() (*string, bool) { + if o == nil || IsNil(o.LastUsedAt) { + return nil, false + } + return o.LastUsedAt, true +} + +// HasLastUsedAt returns a boolean if a field has been set. +func (o *HandlersUserAPIKeyOut) HasLastUsedAt() bool { + if o != nil && !IsNil(o.LastUsedAt) { + return true + } + + return false +} + +// SetLastUsedAt gets a reference to the given string and assigns it to the LastUsedAt field. +func (o *HandlersUserAPIKeyOut) SetLastUsedAt(v string) { + o.LastUsedAt = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *HandlersUserAPIKeyOut) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersUserAPIKeyOut) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *HandlersUserAPIKeyOut) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *HandlersUserAPIKeyOut) SetName(v string) { + o.Name = &v +} + +// GetPlain returns the Plain field value if set, zero value otherwise. +func (o *HandlersUserAPIKeyOut) GetPlain() string { + if o == nil || IsNil(o.Plain) { + var ret string + return ret + } + return *o.Plain +} + +// GetPlainOk returns a tuple with the Plain field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersUserAPIKeyOut) GetPlainOk() (*string, bool) { + if o == nil || IsNil(o.Plain) { + return nil, false + } + return o.Plain, true +} + +// HasPlain returns a boolean if a field has been set. +func (o *HandlersUserAPIKeyOut) HasPlain() bool { + if o != nil && !IsNil(o.Plain) { + return true + } + + return false +} + +// SetPlain gets a reference to the given string and assigns it to the Plain field. +func (o *HandlersUserAPIKeyOut) SetPlain(v string) { + o.Plain = &v +} + +// GetScope returns the Scope field value if set, zero value otherwise. +func (o *HandlersUserAPIKeyOut) GetScope() string { + if o == nil || IsNil(o.Scope) { + var ret string + return ret + } + return *o.Scope +} + +// GetScopeOk returns a tuple with the Scope field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HandlersUserAPIKeyOut) GetScopeOk() (*string, bool) { + if o == nil || IsNil(o.Scope) { + return nil, false + } + return o.Scope, true +} + +// HasScope returns a boolean if a field has been set. +func (o *HandlersUserAPIKeyOut) HasScope() bool { + if o != nil && !IsNil(o.Scope) { + return true + } + + return false +} + +// SetScope gets a reference to the given string and assigns it to the Scope field. +func (o *HandlersUserAPIKeyOut) SetScope(v string) { + o.Scope = &v +} + +func (o HandlersUserAPIKeyOut) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HandlersUserAPIKeyOut) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.ExpiresAt) { + toSerialize["expires_at"] = o.ExpiresAt + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.LastUsedAt) { + toSerialize["last_used_at"] = o.LastUsedAt + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Plain) { + toSerialize["plain"] = o.Plain + } + if !IsNil(o.Scope) { + toSerialize["scope"] = o.Scope + } + return toSerialize, nil +} + +type NullableHandlersUserAPIKeyOut struct { + value *HandlersUserAPIKeyOut + isSet bool +} + +func (v NullableHandlersUserAPIKeyOut) Get() *HandlersUserAPIKeyOut { + return v.value +} + +func (v *NullableHandlersUserAPIKeyOut) Set(val *HandlersUserAPIKeyOut) { + v.value = val + v.isSet = true +} + +func (v NullableHandlersUserAPIKeyOut) IsSet() bool { + return v.isSet +} + +func (v *NullableHandlersUserAPIKeyOut) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHandlersUserAPIKeyOut(val *HandlersUserAPIKeyOut) *NullableHandlersUserAPIKeyOut { + return &NullableHandlersUserAPIKeyOut{value: val, isSet: true} +} + +func (v NullableHandlersUserAPIKeyOut) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHandlersUserAPIKeyOut) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_models_api_key.go b/sdk/go/model_models_api_key.go new file mode 100644 index 0000000..8381468 --- /dev/null +++ b/sdk/go/model_models_api_key.go @@ -0,0 +1,485 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" + "time" +) + +// checks if the ModelsAPIKey type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelsAPIKey{} + +// ModelsAPIKey struct for ModelsAPIKey +type ModelsAPIKey struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + Id *string `json:"id,omitempty"` + LastUsedAt *time.Time `json:"last_used_at,omitempty"` + Name *string `json:"name,omitempty"` + OrgId *string `json:"org_id,omitempty"` + Prefix *string `json:"prefix,omitempty"` + Revoked *bool `json:"revoked,omitempty"` + Scope *string `json:"scope,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + UserId *string `json:"user_id,omitempty"` +} + +// NewModelsAPIKey instantiates a new ModelsAPIKey object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelsAPIKey() *ModelsAPIKey { + this := ModelsAPIKey{} + return &this +} + +// NewModelsAPIKeyWithDefaults instantiates a new ModelsAPIKey object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelsAPIKeyWithDefaults() *ModelsAPIKey { + this := ModelsAPIKey{} + return &this +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetCreatedAt() time.Time { + if o == nil || IsNil(o.CreatedAt) { + var ret time.Time + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetCreatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given time.Time and assigns it to the CreatedAt field. +func (o *ModelsAPIKey) SetCreatedAt(v time.Time) { + o.CreatedAt = &v +} + +// GetExpiresAt returns the ExpiresAt field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetExpiresAt() time.Time { + if o == nil || IsNil(o.ExpiresAt) { + var ret time.Time + return ret + } + return *o.ExpiresAt +} + +// GetExpiresAtOk returns a tuple with the ExpiresAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetExpiresAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.ExpiresAt) { + return nil, false + } + return o.ExpiresAt, true +} + +// HasExpiresAt returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasExpiresAt() bool { + if o != nil && !IsNil(o.ExpiresAt) { + return true + } + + return false +} + +// SetExpiresAt gets a reference to the given time.Time and assigns it to the ExpiresAt field. +func (o *ModelsAPIKey) SetExpiresAt(v time.Time) { + o.ExpiresAt = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *ModelsAPIKey) SetId(v string) { + o.Id = &v +} + +// GetLastUsedAt returns the LastUsedAt field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetLastUsedAt() time.Time { + if o == nil || IsNil(o.LastUsedAt) { + var ret time.Time + return ret + } + return *o.LastUsedAt +} + +// GetLastUsedAtOk returns a tuple with the LastUsedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetLastUsedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.LastUsedAt) { + return nil, false + } + return o.LastUsedAt, true +} + +// HasLastUsedAt returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasLastUsedAt() bool { + if o != nil && !IsNil(o.LastUsedAt) { + return true + } + + return false +} + +// SetLastUsedAt gets a reference to the given time.Time and assigns it to the LastUsedAt field. +func (o *ModelsAPIKey) SetLastUsedAt(v time.Time) { + o.LastUsedAt = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ModelsAPIKey) SetName(v string) { + o.Name = &v +} + +// GetOrgId returns the OrgId field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetOrgId() string { + if o == nil || IsNil(o.OrgId) { + var ret string + return ret + } + return *o.OrgId +} + +// GetOrgIdOk returns a tuple with the OrgId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetOrgIdOk() (*string, bool) { + if o == nil || IsNil(o.OrgId) { + return nil, false + } + return o.OrgId, true +} + +// HasOrgId returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasOrgId() bool { + if o != nil && !IsNil(o.OrgId) { + return true + } + + return false +} + +// SetOrgId gets a reference to the given string and assigns it to the OrgId field. +func (o *ModelsAPIKey) SetOrgId(v string) { + o.OrgId = &v +} + +// GetPrefix returns the Prefix field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetPrefix() string { + if o == nil || IsNil(o.Prefix) { + var ret string + return ret + } + return *o.Prefix +} + +// GetPrefixOk returns a tuple with the Prefix field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetPrefixOk() (*string, bool) { + if o == nil || IsNil(o.Prefix) { + return nil, false + } + return o.Prefix, true +} + +// HasPrefix returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasPrefix() bool { + if o != nil && !IsNil(o.Prefix) { + return true + } + + return false +} + +// SetPrefix gets a reference to the given string and assigns it to the Prefix field. +func (o *ModelsAPIKey) SetPrefix(v string) { + o.Prefix = &v +} + +// GetRevoked returns the Revoked field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetRevoked() bool { + if o == nil || IsNil(o.Revoked) { + var ret bool + return ret + } + return *o.Revoked +} + +// GetRevokedOk returns a tuple with the Revoked field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetRevokedOk() (*bool, bool) { + if o == nil || IsNil(o.Revoked) { + return nil, false + } + return o.Revoked, true +} + +// HasRevoked returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasRevoked() bool { + if o != nil && !IsNil(o.Revoked) { + return true + } + + return false +} + +// SetRevoked gets a reference to the given bool and assigns it to the Revoked field. +func (o *ModelsAPIKey) SetRevoked(v bool) { + o.Revoked = &v +} + +// GetScope returns the Scope field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetScope() string { + if o == nil || IsNil(o.Scope) { + var ret string + return ret + } + return *o.Scope +} + +// GetScopeOk returns a tuple with the Scope field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetScopeOk() (*string, bool) { + if o == nil || IsNil(o.Scope) { + return nil, false + } + return o.Scope, true +} + +// HasScope returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasScope() bool { + if o != nil && !IsNil(o.Scope) { + return true + } + + return false +} + +// SetScope gets a reference to the given string and assigns it to the Scope field. +func (o *ModelsAPIKey) SetScope(v string) { + o.Scope = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetUpdatedAt() time.Time { + if o == nil || IsNil(o.UpdatedAt) { + var ret time.Time + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetUpdatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given time.Time and assigns it to the UpdatedAt field. +func (o *ModelsAPIKey) SetUpdatedAt(v time.Time) { + o.UpdatedAt = &v +} + +// GetUserId returns the UserId field value if set, zero value otherwise. +func (o *ModelsAPIKey) GetUserId() string { + if o == nil || IsNil(o.UserId) { + var ret string + return ret + } + return *o.UserId +} + +// GetUserIdOk returns a tuple with the UserId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsAPIKey) GetUserIdOk() (*string, bool) { + if o == nil || IsNil(o.UserId) { + return nil, false + } + return o.UserId, true +} + +// HasUserId returns a boolean if a field has been set. +func (o *ModelsAPIKey) HasUserId() bool { + if o != nil && !IsNil(o.UserId) { + return true + } + + return false +} + +// SetUserId gets a reference to the given string and assigns it to the UserId field. +func (o *ModelsAPIKey) SetUserId(v string) { + o.UserId = &v +} + +func (o ModelsAPIKey) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelsAPIKey) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.ExpiresAt) { + toSerialize["expires_at"] = o.ExpiresAt + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.LastUsedAt) { + toSerialize["last_used_at"] = o.LastUsedAt + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.OrgId) { + toSerialize["org_id"] = o.OrgId + } + if !IsNil(o.Prefix) { + toSerialize["prefix"] = o.Prefix + } + if !IsNil(o.Revoked) { + toSerialize["revoked"] = o.Revoked + } + if !IsNil(o.Scope) { + toSerialize["scope"] = o.Scope + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + if !IsNil(o.UserId) { + toSerialize["user_id"] = o.UserId + } + return toSerialize, nil +} + +type NullableModelsAPIKey struct { + value *ModelsAPIKey + isSet bool +} + +func (v NullableModelsAPIKey) Get() *ModelsAPIKey { + return v.value +} + +func (v *NullableModelsAPIKey) Set(val *ModelsAPIKey) { + v.value = val + v.isSet = true +} + +func (v NullableModelsAPIKey) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsAPIKey) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsAPIKey(val *ModelsAPIKey) *NullableModelsAPIKey { + return &NullableModelsAPIKey{value: val, isSet: true} +} + +func (v NullableModelsAPIKey) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsAPIKey) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_models_organization.go b/sdk/go/model_models_organization.go new file mode 100644 index 0000000..1fb1734 --- /dev/null +++ b/sdk/go/model_models_organization.go @@ -0,0 +1,270 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" + "time" +) + +// checks if the ModelsOrganization type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelsOrganization{} + +// ModelsOrganization struct for ModelsOrganization +type ModelsOrganization struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + Domain *string `json:"domain,omitempty"` + // example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// NewModelsOrganization instantiates a new ModelsOrganization object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelsOrganization() *ModelsOrganization { + this := ModelsOrganization{} + return &this +} + +// NewModelsOrganizationWithDefaults instantiates a new ModelsOrganization object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelsOrganizationWithDefaults() *ModelsOrganization { + this := ModelsOrganization{} + return &this +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *ModelsOrganization) GetCreatedAt() time.Time { + if o == nil || IsNil(o.CreatedAt) { + var ret time.Time + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsOrganization) GetCreatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *ModelsOrganization) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given time.Time and assigns it to the CreatedAt field. +func (o *ModelsOrganization) SetCreatedAt(v time.Time) { + o.CreatedAt = &v +} + +// GetDomain returns the Domain field value if set, zero value otherwise. +func (o *ModelsOrganization) GetDomain() string { + if o == nil || IsNil(o.Domain) { + var ret string + return ret + } + return *o.Domain +} + +// GetDomainOk returns a tuple with the Domain field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsOrganization) GetDomainOk() (*string, bool) { + if o == nil || IsNil(o.Domain) { + return nil, false + } + return o.Domain, true +} + +// HasDomain returns a boolean if a field has been set. +func (o *ModelsOrganization) HasDomain() bool { + if o != nil && !IsNil(o.Domain) { + return true + } + + return false +} + +// SetDomain gets a reference to the given string and assigns it to the Domain field. +func (o *ModelsOrganization) SetDomain(v string) { + o.Domain = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *ModelsOrganization) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsOrganization) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *ModelsOrganization) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *ModelsOrganization) SetId(v string) { + o.Id = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ModelsOrganization) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsOrganization) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ModelsOrganization) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ModelsOrganization) SetName(v string) { + o.Name = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *ModelsOrganization) GetUpdatedAt() time.Time { + if o == nil || IsNil(o.UpdatedAt) { + var ret time.Time + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsOrganization) GetUpdatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *ModelsOrganization) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given time.Time and assigns it to the UpdatedAt field. +func (o *ModelsOrganization) SetUpdatedAt(v time.Time) { + o.UpdatedAt = &v +} + +func (o ModelsOrganization) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelsOrganization) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.Domain) { + toSerialize["domain"] = o.Domain + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + return toSerialize, nil +} + +type NullableModelsOrganization struct { + value *ModelsOrganization + isSet bool +} + +func (v NullableModelsOrganization) Get() *ModelsOrganization { + return v.value +} + +func (v *NullableModelsOrganization) Set(val *ModelsOrganization) { + v.value = val + v.isSet = true +} + +func (v NullableModelsOrganization) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsOrganization) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsOrganization(val *ModelsOrganization) *NullableModelsOrganization { + return &NullableModelsOrganization{value: val, isSet: true} +} + +func (v NullableModelsOrganization) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsOrganization) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_models_user.go b/sdk/go/model_models_user.go new file mode 100644 index 0000000..07886e6 --- /dev/null +++ b/sdk/go/model_models_user.go @@ -0,0 +1,342 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" + "time" +) + +// checks if the ModelsUser type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelsUser{} + +// ModelsUser struct for ModelsUser +type ModelsUser struct { + AvatarUrl *string `json:"avatar_url,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + // example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + Id *string `json:"id,omitempty"` + IsDisabled *bool `json:"is_disabled,omitempty"` + PrimaryEmail *string `json:"primary_email,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// NewModelsUser instantiates a new ModelsUser object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelsUser() *ModelsUser { + this := ModelsUser{} + return &this +} + +// NewModelsUserWithDefaults instantiates a new ModelsUser object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelsUserWithDefaults() *ModelsUser { + this := ModelsUser{} + return &this +} + +// GetAvatarUrl returns the AvatarUrl field value if set, zero value otherwise. +func (o *ModelsUser) GetAvatarUrl() string { + if o == nil || IsNil(o.AvatarUrl) { + var ret string + return ret + } + return *o.AvatarUrl +} + +// GetAvatarUrlOk returns a tuple with the AvatarUrl field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUser) GetAvatarUrlOk() (*string, bool) { + if o == nil || IsNil(o.AvatarUrl) { + return nil, false + } + return o.AvatarUrl, true +} + +// HasAvatarUrl returns a boolean if a field has been set. +func (o *ModelsUser) HasAvatarUrl() bool { + if o != nil && !IsNil(o.AvatarUrl) { + return true + } + + return false +} + +// SetAvatarUrl gets a reference to the given string and assigns it to the AvatarUrl field. +func (o *ModelsUser) SetAvatarUrl(v string) { + o.AvatarUrl = &v +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *ModelsUser) GetCreatedAt() time.Time { + if o == nil || IsNil(o.CreatedAt) { + var ret time.Time + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUser) GetCreatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *ModelsUser) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given time.Time and assigns it to the CreatedAt field. +func (o *ModelsUser) SetCreatedAt(v time.Time) { + o.CreatedAt = &v +} + +// GetDisplayName returns the DisplayName field value if set, zero value otherwise. +func (o *ModelsUser) GetDisplayName() string { + if o == nil || IsNil(o.DisplayName) { + var ret string + return ret + } + return *o.DisplayName +} + +// GetDisplayNameOk returns a tuple with the DisplayName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUser) GetDisplayNameOk() (*string, bool) { + if o == nil || IsNil(o.DisplayName) { + return nil, false + } + return o.DisplayName, true +} + +// HasDisplayName returns a boolean if a field has been set. +func (o *ModelsUser) HasDisplayName() bool { + if o != nil && !IsNil(o.DisplayName) { + return true + } + + return false +} + +// SetDisplayName gets a reference to the given string and assigns it to the DisplayName field. +func (o *ModelsUser) SetDisplayName(v string) { + o.DisplayName = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *ModelsUser) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUser) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *ModelsUser) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *ModelsUser) SetId(v string) { + o.Id = &v +} + +// GetIsDisabled returns the IsDisabled field value if set, zero value otherwise. +func (o *ModelsUser) GetIsDisabled() bool { + if o == nil || IsNil(o.IsDisabled) { + var ret bool + return ret + } + return *o.IsDisabled +} + +// GetIsDisabledOk returns a tuple with the IsDisabled field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUser) GetIsDisabledOk() (*bool, bool) { + if o == nil || IsNil(o.IsDisabled) { + return nil, false + } + return o.IsDisabled, true +} + +// HasIsDisabled returns a boolean if a field has been set. +func (o *ModelsUser) HasIsDisabled() bool { + if o != nil && !IsNil(o.IsDisabled) { + return true + } + + return false +} + +// SetIsDisabled gets a reference to the given bool and assigns it to the IsDisabled field. +func (o *ModelsUser) SetIsDisabled(v bool) { + o.IsDisabled = &v +} + +// GetPrimaryEmail returns the PrimaryEmail field value if set, zero value otherwise. +func (o *ModelsUser) GetPrimaryEmail() string { + if o == nil || IsNil(o.PrimaryEmail) { + var ret string + return ret + } + return *o.PrimaryEmail +} + +// GetPrimaryEmailOk returns a tuple with the PrimaryEmail field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUser) GetPrimaryEmailOk() (*string, bool) { + if o == nil || IsNil(o.PrimaryEmail) { + return nil, false + } + return o.PrimaryEmail, true +} + +// HasPrimaryEmail returns a boolean if a field has been set. +func (o *ModelsUser) HasPrimaryEmail() bool { + if o != nil && !IsNil(o.PrimaryEmail) { + return true + } + + return false +} + +// SetPrimaryEmail gets a reference to the given string and assigns it to the PrimaryEmail field. +func (o *ModelsUser) SetPrimaryEmail(v string) { + o.PrimaryEmail = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *ModelsUser) GetUpdatedAt() time.Time { + if o == nil || IsNil(o.UpdatedAt) { + var ret time.Time + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUser) GetUpdatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *ModelsUser) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given time.Time and assigns it to the UpdatedAt field. +func (o *ModelsUser) SetUpdatedAt(v time.Time) { + o.UpdatedAt = &v +} + +func (o ModelsUser) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelsUser) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.AvatarUrl) { + toSerialize["avatar_url"] = o.AvatarUrl + } + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.DisplayName) { + toSerialize["display_name"] = o.DisplayName + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.IsDisabled) { + toSerialize["is_disabled"] = o.IsDisabled + } + if !IsNil(o.PrimaryEmail) { + toSerialize["primary_email"] = o.PrimaryEmail + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + return toSerialize, nil +} + +type NullableModelsUser struct { + value *ModelsUser + isSet bool +} + +func (v NullableModelsUser) Get() *ModelsUser { + return v.value +} + +func (v *NullableModelsUser) Set(val *ModelsUser) { + v.value = val + v.isSet = true +} + +func (v NullableModelsUser) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsUser) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsUser(val *ModelsUser) *NullableModelsUser { + return &NullableModelsUser{value: val, isSet: true} +} + +func (v NullableModelsUser) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsUser) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_models_user_email.go b/sdk/go/model_models_user_email.go new file mode 100644 index 0000000..4c33d6c --- /dev/null +++ b/sdk/go/model_models_user_email.go @@ -0,0 +1,378 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" + "time" +) + +// checks if the ModelsUserEmail type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelsUserEmail{} + +// ModelsUserEmail struct for ModelsUserEmail +type ModelsUserEmail struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + Email *string `json:"email,omitempty"` + // example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + Id *string `json:"id,omitempty"` + IsPrimary *bool `json:"is_primary,omitempty"` + IsVerified *bool `json:"is_verified,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + User *ModelsUser `json:"user,omitempty"` + UserId *string `json:"user_id,omitempty"` +} + +// NewModelsUserEmail instantiates a new ModelsUserEmail object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelsUserEmail() *ModelsUserEmail { + this := ModelsUserEmail{} + return &this +} + +// NewModelsUserEmailWithDefaults instantiates a new ModelsUserEmail object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelsUserEmailWithDefaults() *ModelsUserEmail { + this := ModelsUserEmail{} + return &this +} + +// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise. +func (o *ModelsUserEmail) GetCreatedAt() time.Time { + if o == nil || IsNil(o.CreatedAt) { + var ret time.Time + return ret + } + return *o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUserEmail) GetCreatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.CreatedAt) { + return nil, false + } + return o.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (o *ModelsUserEmail) HasCreatedAt() bool { + if o != nil && !IsNil(o.CreatedAt) { + return true + } + + return false +} + +// SetCreatedAt gets a reference to the given time.Time and assigns it to the CreatedAt field. +func (o *ModelsUserEmail) SetCreatedAt(v time.Time) { + o.CreatedAt = &v +} + +// GetEmail returns the Email field value if set, zero value otherwise. +func (o *ModelsUserEmail) GetEmail() string { + if o == nil || IsNil(o.Email) { + var ret string + return ret + } + return *o.Email +} + +// GetEmailOk returns a tuple with the Email field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUserEmail) GetEmailOk() (*string, bool) { + if o == nil || IsNil(o.Email) { + return nil, false + } + return o.Email, true +} + +// HasEmail returns a boolean if a field has been set. +func (o *ModelsUserEmail) HasEmail() bool { + if o != nil && !IsNil(o.Email) { + return true + } + + return false +} + +// SetEmail gets a reference to the given string and assigns it to the Email field. +func (o *ModelsUserEmail) SetEmail(v string) { + o.Email = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *ModelsUserEmail) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUserEmail) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *ModelsUserEmail) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *ModelsUserEmail) SetId(v string) { + o.Id = &v +} + +// GetIsPrimary returns the IsPrimary field value if set, zero value otherwise. +func (o *ModelsUserEmail) GetIsPrimary() bool { + if o == nil || IsNil(o.IsPrimary) { + var ret bool + return ret + } + return *o.IsPrimary +} + +// GetIsPrimaryOk returns a tuple with the IsPrimary field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUserEmail) GetIsPrimaryOk() (*bool, bool) { + if o == nil || IsNil(o.IsPrimary) { + return nil, false + } + return o.IsPrimary, true +} + +// HasIsPrimary returns a boolean if a field has been set. +func (o *ModelsUserEmail) HasIsPrimary() bool { + if o != nil && !IsNil(o.IsPrimary) { + return true + } + + return false +} + +// SetIsPrimary gets a reference to the given bool and assigns it to the IsPrimary field. +func (o *ModelsUserEmail) SetIsPrimary(v bool) { + o.IsPrimary = &v +} + +// GetIsVerified returns the IsVerified field value if set, zero value otherwise. +func (o *ModelsUserEmail) GetIsVerified() bool { + if o == nil || IsNil(o.IsVerified) { + var ret bool + return ret + } + return *o.IsVerified +} + +// GetIsVerifiedOk returns a tuple with the IsVerified field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUserEmail) GetIsVerifiedOk() (*bool, bool) { + if o == nil || IsNil(o.IsVerified) { + return nil, false + } + return o.IsVerified, true +} + +// HasIsVerified returns a boolean if a field has been set. +func (o *ModelsUserEmail) HasIsVerified() bool { + if o != nil && !IsNil(o.IsVerified) { + return true + } + + return false +} + +// SetIsVerified gets a reference to the given bool and assigns it to the IsVerified field. +func (o *ModelsUserEmail) SetIsVerified(v bool) { + o.IsVerified = &v +} + +// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise. +func (o *ModelsUserEmail) GetUpdatedAt() time.Time { + if o == nil || IsNil(o.UpdatedAt) { + var ret time.Time + return ret + } + return *o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUserEmail) GetUpdatedAtOk() (*time.Time, bool) { + if o == nil || IsNil(o.UpdatedAt) { + return nil, false + } + return o.UpdatedAt, true +} + +// HasUpdatedAt returns a boolean if a field has been set. +func (o *ModelsUserEmail) HasUpdatedAt() bool { + if o != nil && !IsNil(o.UpdatedAt) { + return true + } + + return false +} + +// SetUpdatedAt gets a reference to the given time.Time and assigns it to the UpdatedAt field. +func (o *ModelsUserEmail) SetUpdatedAt(v time.Time) { + o.UpdatedAt = &v +} + +// GetUser returns the User field value if set, zero value otherwise. +func (o *ModelsUserEmail) GetUser() ModelsUser { + if o == nil || IsNil(o.User) { + var ret ModelsUser + return ret + } + return *o.User +} + +// GetUserOk returns a tuple with the User field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUserEmail) GetUserOk() (*ModelsUser, bool) { + if o == nil || IsNil(o.User) { + return nil, false + } + return o.User, true +} + +// HasUser returns a boolean if a field has been set. +func (o *ModelsUserEmail) HasUser() bool { + if o != nil && !IsNil(o.User) { + return true + } + + return false +} + +// SetUser gets a reference to the given ModelsUser and assigns it to the User field. +func (o *ModelsUserEmail) SetUser(v ModelsUser) { + o.User = &v +} + +// GetUserId returns the UserId field value if set, zero value otherwise. +func (o *ModelsUserEmail) GetUserId() string { + if o == nil || IsNil(o.UserId) { + var ret string + return ret + } + return *o.UserId +} + +// GetUserIdOk returns a tuple with the UserId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelsUserEmail) GetUserIdOk() (*string, bool) { + if o == nil || IsNil(o.UserId) { + return nil, false + } + return o.UserId, true +} + +// HasUserId returns a boolean if a field has been set. +func (o *ModelsUserEmail) HasUserId() bool { + if o != nil && !IsNil(o.UserId) { + return true + } + + return false +} + +// SetUserId gets a reference to the given string and assigns it to the UserId field. +func (o *ModelsUserEmail) SetUserId(v string) { + o.UserId = &v +} + +func (o ModelsUserEmail) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelsUserEmail) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CreatedAt) { + toSerialize["created_at"] = o.CreatedAt + } + if !IsNil(o.Email) { + toSerialize["email"] = o.Email + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.IsPrimary) { + toSerialize["is_primary"] = o.IsPrimary + } + if !IsNil(o.IsVerified) { + toSerialize["is_verified"] = o.IsVerified + } + if !IsNil(o.UpdatedAt) { + toSerialize["updated_at"] = o.UpdatedAt + } + if !IsNil(o.User) { + toSerialize["user"] = o.User + } + if !IsNil(o.UserId) { + toSerialize["user_id"] = o.UserId + } + return toSerialize, nil +} + +type NullableModelsUserEmail struct { + value *ModelsUserEmail + isSet bool +} + +func (v NullableModelsUserEmail) Get() *ModelsUserEmail { + return v.value +} + +func (v *NullableModelsUserEmail) Set(val *ModelsUserEmail) { + v.value = val + v.isSet = true +} + +func (v NullableModelsUserEmail) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsUserEmail) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsUserEmail(val *ModelsUserEmail) *NullableModelsUserEmail { + return &NullableModelsUserEmail{value: val, isSet: true} +} + +func (v NullableModelsUserEmail) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsUserEmail) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/model_utils_error_response.go b/sdk/go/model_utils_error_response.go new file mode 100644 index 0000000..b1bfa6f --- /dev/null +++ b/sdk/go/model_utils_error_response.go @@ -0,0 +1,162 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "encoding/json" +) + +// checks if the UtilsErrorResponse type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &UtilsErrorResponse{} + +// UtilsErrorResponse struct for UtilsErrorResponse +type UtilsErrorResponse struct { + // A machine-readable error code, e.g. \"validation_error\" example: validation_error + Code *string `json:"code,omitempty"` + // Human-readable message example: slug is required + Message *string `json:"message,omitempty"` +} + +// NewUtilsErrorResponse instantiates a new UtilsErrorResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUtilsErrorResponse() *UtilsErrorResponse { + this := UtilsErrorResponse{} + return &this +} + +// NewUtilsErrorResponseWithDefaults instantiates a new UtilsErrorResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUtilsErrorResponseWithDefaults() *UtilsErrorResponse { + this := UtilsErrorResponse{} + return &this +} + +// GetCode returns the Code field value if set, zero value otherwise. +func (o *UtilsErrorResponse) GetCode() string { + if o == nil || IsNil(o.Code) { + var ret string + return ret + } + return *o.Code +} + +// GetCodeOk returns a tuple with the Code field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UtilsErrorResponse) GetCodeOk() (*string, bool) { + if o == nil || IsNil(o.Code) { + return nil, false + } + return o.Code, true +} + +// HasCode returns a boolean if a field has been set. +func (o *UtilsErrorResponse) HasCode() bool { + if o != nil && !IsNil(o.Code) { + return true + } + + return false +} + +// SetCode gets a reference to the given string and assigns it to the Code field. +func (o *UtilsErrorResponse) SetCode(v string) { + o.Code = &v +} + +// GetMessage returns the Message field value if set, zero value otherwise. +func (o *UtilsErrorResponse) GetMessage() string { + if o == nil || IsNil(o.Message) { + var ret string + return ret + } + return *o.Message +} + +// GetMessageOk returns a tuple with the Message field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UtilsErrorResponse) GetMessageOk() (*string, bool) { + if o == nil || IsNil(o.Message) { + return nil, false + } + return o.Message, true +} + +// HasMessage returns a boolean if a field has been set. +func (o *UtilsErrorResponse) HasMessage() bool { + if o != nil && !IsNil(o.Message) { + return true + } + + return false +} + +// SetMessage gets a reference to the given string and assigns it to the Message field. +func (o *UtilsErrorResponse) SetMessage(v string) { + o.Message = &v +} + +func (o UtilsErrorResponse) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o UtilsErrorResponse) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Code) { + toSerialize["code"] = o.Code + } + if !IsNil(o.Message) { + toSerialize["message"] = o.Message + } + return toSerialize, nil +} + +type NullableUtilsErrorResponse struct { + value *UtilsErrorResponse + isSet bool +} + +func (v NullableUtilsErrorResponse) Get() *UtilsErrorResponse { + return v.value +} + +func (v *NullableUtilsErrorResponse) Set(val *UtilsErrorResponse) { + v.value = val + v.isSet = true +} + +func (v NullableUtilsErrorResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableUtilsErrorResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUtilsErrorResponse(val *UtilsErrorResponse) *NullableUtilsErrorResponse { + return &NullableUtilsErrorResponse{value: val, isSet: true} +} + +func (v NullableUtilsErrorResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUtilsErrorResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/sdk/go/response.go b/sdk/go/response.go new file mode 100644 index 0000000..5d86157 --- /dev/null +++ b/sdk/go/response.go @@ -0,0 +1,47 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "net/http" +) + +// APIResponse stores the API response returned by the server. +type APIResponse struct { + *http.Response `json:"-"` + Message string `json:"message,omitempty"` + // Operation is the name of the OpenAPI operation. + Operation string `json:"operation,omitempty"` + // RequestURL is the request URL. This value is always available, even if the + // embedded *http.Response is nil. + RequestURL string `json:"url,omitempty"` + // Method is the HTTP method used for the request. This value is always + // available, even if the embedded *http.Response is nil. + Method string `json:"method,omitempty"` + // Payload holds the contents of the response body (which may be nil or empty). + // This is provided here as the raw response.Body() reader will have already + // been drained. + Payload []byte `json:"-"` +} + +// NewAPIResponse returns a new APIResponse object. +func NewAPIResponse(r *http.Response) *APIResponse { + + response := &APIResponse{Response: r} + return response +} + +// NewAPIResponseWithError returns a new APIResponse object with the provided error message. +func NewAPIResponseWithError(errorMessage string) *APIResponse { + + response := &APIResponse{Message: errorMessage} + return response +} diff --git a/sdk/go/test/api_auth_test.go b/sdk/go/test/api_auth_test.go new file mode 100644 index 0000000..e7b041a --- /dev/null +++ b/sdk/go/test/api_auth_test.go @@ -0,0 +1,37 @@ +/* +AutoGlue API + +Testing AuthAPIService + +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); + +package autoglue + +import ( + "context" + openapiclient "github.com/glueops/autoglue-sdk" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func Test_autoglue_AuthAPIService(t *testing.T) { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + + t.Run("Test AuthAPIService GetJWKS", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.AuthAPI.GetJWKS(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + +} diff --git a/sdk/go/test/api_me_api_keys_test.go b/sdk/go/test/api_me_api_keys_test.go new file mode 100644 index 0000000..050b7d5 --- /dev/null +++ b/sdk/go/test/api_me_api_keys_test.go @@ -0,0 +1,62 @@ +/* +AutoGlue API + +Testing MeAPIKeysAPIService + +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); + +package autoglue + +import ( + "context" + openapiclient "github.com/glueops/autoglue-sdk" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func Test_autoglue_MeAPIKeysAPIService(t *testing.T) { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + + t.Run("Test MeAPIKeysAPIService CreateUserAPIKey", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.MeAPIKeysAPI.CreateUserAPIKey(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test MeAPIKeysAPIService DeleteUserAPIKey", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + httpRes, err := apiClient.MeAPIKeysAPI.DeleteUserAPIKey(context.Background(), id).Execute() + + require.Nil(t, err) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test MeAPIKeysAPIService ListUserAPIKeys", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.MeAPIKeysAPI.ListUserAPIKeys(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + +} diff --git a/sdk/go/test/api_me_test.go b/sdk/go/test/api_me_test.go new file mode 100644 index 0000000..f347da1 --- /dev/null +++ b/sdk/go/test/api_me_test.go @@ -0,0 +1,37 @@ +/* +AutoGlue API + +Testing MeAPIService + +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); + +package autoglue + +import ( + "context" + openapiclient "github.com/glueops/autoglue-sdk" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func Test_autoglue_MeAPIService(t *testing.T) { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + + t.Run("Test MeAPIService GetMe", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.MeAPI.GetMe(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + +} diff --git a/sdk/go/test/api_orgs_test.go b/sdk/go/test/api_orgs_test.go new file mode 100644 index 0000000..4a49177 --- /dev/null +++ b/sdk/go/test/api_orgs_test.go @@ -0,0 +1,49 @@ +/* +AutoGlue API + +Testing OrgsAPIService + +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); + +package autoglue + +import ( + "context" + openapiclient "github.com/glueops/autoglue-sdk" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func Test_autoglue_OrgsAPIService(t *testing.T) { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + + t.Run("Test OrgsAPIService CreateOrg", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.OrgsAPI.CreateOrg(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test OrgsAPIService ListMyOrgs", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.OrgsAPI.ListMyOrgs(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + +} diff --git a/sdk/go/test/api_servers_test.go b/sdk/go/test/api_servers_test.go new file mode 100644 index 0000000..ec84831 --- /dev/null +++ b/sdk/go/test/api_servers_test.go @@ -0,0 +1,91 @@ +/* +AutoGlue API + +Testing ServersAPIService + +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); + +package autoglue + +import ( + "context" + openapiclient "github.com/glueops/autoglue-sdk" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func Test_autoglue_ServersAPIService(t *testing.T) { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + + t.Run("Test ServersAPIService CreateServer", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.ServersAPI.CreateServer(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test ServersAPIService DeleteServer", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.ServersAPI.DeleteServer(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test ServersAPIService GetServer", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.ServersAPI.GetServer(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test ServersAPIService ListServers", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.ServersAPI.ListServers(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test ServersAPIService UpdateServer", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.ServersAPI.UpdateServer(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + +} diff --git a/sdk/go/test/api_ssh_test.go b/sdk/go/test/api_ssh_test.go new file mode 100644 index 0000000..f2b3c74 --- /dev/null +++ b/sdk/go/test/api_ssh_test.go @@ -0,0 +1,91 @@ +/* +AutoGlue API + +Testing SshAPIService + +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); + +package autoglue + +import ( + "context" + openapiclient "github.com/glueops/autoglue-sdk" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func Test_autoglue_SshAPIService(t *testing.T) { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + + t.Run("Test SshAPIService CreateSSHKey", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.SshAPI.CreateSSHKey(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test SshAPIService DeleteSSHKey", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.SshAPI.DeleteSSHKey(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test SshAPIService DownloadSSHKey", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.SshAPI.DownloadSSHKey(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test SshAPIService GetSSHKey", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.SshAPI.GetSSHKey(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test SshAPIService ListPublicSshKeys", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.SshAPI.ListPublicSshKeys(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + +} diff --git a/sdk/go/test/api_taints_test.go b/sdk/go/test/api_taints_test.go new file mode 100644 index 0000000..55a6de1 --- /dev/null +++ b/sdk/go/test/api_taints_test.go @@ -0,0 +1,91 @@ +/* +AutoGlue API + +Testing TaintsAPIService + +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); + +package autoglue + +import ( + "context" + openapiclient "github.com/glueops/autoglue-sdk" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func Test_autoglue_TaintsAPIService(t *testing.T) { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + + t.Run("Test TaintsAPIService CreateTaint", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.TaintsAPI.CreateTaint(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test TaintsAPIService DeleteTaint", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.TaintsAPI.DeleteTaint(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test TaintsAPIService GetTaint", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.TaintsAPI.GetTaint(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test TaintsAPIService ListTaints", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.TaintsAPI.ListTaints(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + + t.Run("Test TaintsAPIService UpdateTaint", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + var id string + + resp, httpRes, err := apiClient.TaintsAPI.UpdateTaint(context.Background(), id).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + +} diff --git a/sdk/go/utils.go b/sdk/go/utils.go new file mode 100644 index 0000000..e6c2711 --- /dev/null +++ b/sdk/go/utils.go @@ -0,0 +1,361 @@ +/* +AutoGlue API + +API for managing K3s clusters across cloud providers + +API version: 1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package autoglue + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "time" +) + +// PtrBool is a helper routine that returns a pointer to given boolean value. +func PtrBool(v bool) *bool { return &v } + +// PtrInt is a helper routine that returns a pointer to given integer value. +func PtrInt(v int) *int { return &v } + +// PtrInt32 is a helper routine that returns a pointer to given integer value. +func PtrInt32(v int32) *int32 { return &v } + +// PtrInt64 is a helper routine that returns a pointer to given integer value. +func PtrInt64(v int64) *int64 { return &v } + +// PtrFloat32 is a helper routine that returns a pointer to given float value. +func PtrFloat32(v float32) *float32 { return &v } + +// PtrFloat64 is a helper routine that returns a pointer to given float value. +func PtrFloat64(v float64) *float64 { return &v } + +// PtrString is a helper routine that returns a pointer to given string value. +func PtrString(v string) *string { return &v } + +// PtrTime is helper routine that returns a pointer to given Time value. +func PtrTime(v time.Time) *time.Time { return &v } + +type NullableBool struct { + value *bool + isSet bool +} + +func (v NullableBool) Get() *bool { + return v.value +} + +func (v *NullableBool) Set(val *bool) { + v.value = val + v.isSet = true +} + +func (v NullableBool) IsSet() bool { + return v.isSet +} + +func (v *NullableBool) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBool(val *bool) *NullableBool { + return &NullableBool{value: val, isSet: true} +} + +func (v NullableBool) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBool) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt struct { + value *int + isSet bool +} + +func (v NullableInt) Get() *int { + return v.value +} + +func (v *NullableInt) Set(val *int) { + v.value = val + v.isSet = true +} + +func (v NullableInt) IsSet() bool { + return v.isSet +} + +func (v *NullableInt) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt(val *int) *NullableInt { + return &NullableInt{value: val, isSet: true} +} + +func (v NullableInt) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt32 struct { + value *int32 + isSet bool +} + +func (v NullableInt32) Get() *int32 { + return v.value +} + +func (v *NullableInt32) Set(val *int32) { + v.value = val + v.isSet = true +} + +func (v NullableInt32) IsSet() bool { + return v.isSet +} + +func (v *NullableInt32) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt32(val *int32) *NullableInt32 { + return &NullableInt32{value: val, isSet: true} +} + +func (v NullableInt32) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt32) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt64 struct { + value *int64 + isSet bool +} + +func (v NullableInt64) Get() *int64 { + return v.value +} + +func (v *NullableInt64) Set(val *int64) { + v.value = val + v.isSet = true +} + +func (v NullableInt64) IsSet() bool { + return v.isSet +} + +func (v *NullableInt64) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt64(val *int64) *NullableInt64 { + return &NullableInt64{value: val, isSet: true} +} + +func (v NullableInt64) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt64) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableFloat32 struct { + value *float32 + isSet bool +} + +func (v NullableFloat32) Get() *float32 { + return v.value +} + +func (v *NullableFloat32) Set(val *float32) { + v.value = val + v.isSet = true +} + +func (v NullableFloat32) IsSet() bool { + return v.isSet +} + +func (v *NullableFloat32) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFloat32(val *float32) *NullableFloat32 { + return &NullableFloat32{value: val, isSet: true} +} + +func (v NullableFloat32) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFloat32) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableFloat64 struct { + value *float64 + isSet bool +} + +func (v NullableFloat64) Get() *float64 { + return v.value +} + +func (v *NullableFloat64) Set(val *float64) { + v.value = val + v.isSet = true +} + +func (v NullableFloat64) IsSet() bool { + return v.isSet +} + +func (v *NullableFloat64) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFloat64(val *float64) *NullableFloat64 { + return &NullableFloat64{value: val, isSet: true} +} + +func (v NullableFloat64) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFloat64) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableString struct { + value *string + isSet bool +} + +func (v NullableString) Get() *string { + return v.value +} + +func (v *NullableString) Set(val *string) { + v.value = val + v.isSet = true +} + +func (v NullableString) IsSet() bool { + return v.isSet +} + +func (v *NullableString) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableString(val *string) *NullableString { + return &NullableString{value: val, isSet: true} +} + +func (v NullableString) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableString) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableTime struct { + value *time.Time + isSet bool +} + +func (v NullableTime) Get() *time.Time { + return v.value +} + +func (v *NullableTime) Set(val *time.Time) { + v.value = val + v.isSet = true +} + +func (v NullableTime) IsSet() bool { + return v.isSet +} + +func (v *NullableTime) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableTime(val *time.Time) *NullableTime { + return &NullableTime{value: val, isSet: true} +} + +func (v NullableTime) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableTime) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +// IsNil checks if an input is nil +func IsNil(i interface{}) bool { + if i == nil { + return true + } + switch reflect.TypeOf(i).Kind() { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice: + return reflect.ValueOf(i).IsNil() + case reflect.Array: + return reflect.ValueOf(i).IsZero() + } + return false +} + +type MappedNullable interface { + ToMap() (map[string]interface{}, error) +} + +// A wrapper for strict JSON decoding +func newStrictDecoder(data []byte) *json.Decoder { + dec := json.NewDecoder(bytes.NewBuffer(data)) + dec.DisallowUnknownFields() + return dec +} + +// Prevent trying to import "fmt" +func reportError(format string, a ...interface{}) error { + return fmt.Errorf(format, a...) +} diff --git a/sdk/ts/.gitignore b/sdk/ts/.gitignore new file mode 100644 index 0000000..149b576 --- /dev/null +++ b/sdk/ts/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/sdk/ts/.npmignore b/sdk/ts/.npmignore new file mode 100644 index 0000000..42061c0 --- /dev/null +++ b/sdk/ts/.npmignore @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/sdk/ts/.openapi-generator-ignore b/sdk/ts/.openapi-generator-ignore new file mode 100644 index 0000000..7484ee5 --- /dev/null +++ b/sdk/ts/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/sdk/ts/.openapi-generator/FILES b/sdk/ts/.openapi-generator/FILES new file mode 100644 index 0000000..743d966 --- /dev/null +++ b/sdk/ts/.openapi-generator/FILES @@ -0,0 +1,85 @@ +.gitignore +.npmignore +.openapi-generator-ignore +README.md +docs/AuthApi.md +docs/DtoAuthStartResponse.md +docs/DtoCreateSSHRequest.md +docs/DtoCreateServerRequest.md +docs/DtoCreateTaintRequest.md +docs/DtoJWK.md +docs/DtoJWKS.md +docs/DtoLogoutRequest.md +docs/DtoRefreshRequest.md +docs/DtoServerResponse.md +docs/DtoSshResponse.md +docs/DtoSshRevealResponse.md +docs/DtoTaintResponse.md +docs/DtoTokenPair.md +docs/DtoUpdateServerRequest.md +docs/DtoUpdateTaintRequest.md +docs/HandlersCreateUserKeyRequest.md +docs/HandlersMeResponse.md +docs/HandlersMemberOut.md +docs/HandlersMemberUpsertReq.md +docs/HandlersOrgCreateReq.md +docs/HandlersOrgKeyCreateReq.md +docs/HandlersOrgKeyCreateResp.md +docs/HandlersOrgUpdateReq.md +docs/HandlersUpdateMeRequest.md +docs/HandlersUserAPIKeyOut.md +docs/MeAPIKeysApi.md +docs/MeApi.md +docs/ModelsAPIKey.md +docs/ModelsOrganization.md +docs/ModelsUser.md +docs/ModelsUserEmail.md +docs/OrgsApi.md +docs/ServersApi.md +docs/SshApi.md +docs/TaintsApi.md +docs/UtilsErrorResponse.md +package.json +src/apis/AuthApi.ts +src/apis/MeAPIKeysApi.ts +src/apis/MeApi.ts +src/apis/OrgsApi.ts +src/apis/ServersApi.ts +src/apis/SshApi.ts +src/apis/TaintsApi.ts +src/apis/index.ts +src/index.ts +src/models/DtoAuthStartResponse.ts +src/models/DtoCreateSSHRequest.ts +src/models/DtoCreateServerRequest.ts +src/models/DtoCreateTaintRequest.ts +src/models/DtoJWK.ts +src/models/DtoJWKS.ts +src/models/DtoLogoutRequest.ts +src/models/DtoRefreshRequest.ts +src/models/DtoServerResponse.ts +src/models/DtoSshResponse.ts +src/models/DtoSshRevealResponse.ts +src/models/DtoTaintResponse.ts +src/models/DtoTokenPair.ts +src/models/DtoUpdateServerRequest.ts +src/models/DtoUpdateTaintRequest.ts +src/models/HandlersCreateUserKeyRequest.ts +src/models/HandlersMeResponse.ts +src/models/HandlersMemberOut.ts +src/models/HandlersMemberUpsertReq.ts +src/models/HandlersOrgCreateReq.ts +src/models/HandlersOrgKeyCreateReq.ts +src/models/HandlersOrgKeyCreateResp.ts +src/models/HandlersOrgUpdateReq.ts +src/models/HandlersUpdateMeRequest.ts +src/models/HandlersUserAPIKeyOut.ts +src/models/ModelsAPIKey.ts +src/models/ModelsOrganization.ts +src/models/ModelsUser.ts +src/models/ModelsUserEmail.ts +src/models/UtilsErrorResponse.ts +src/models/index.ts +src/runtime.ts +tsconfig.esm.json +tsconfig.json diff --git a/sdk/ts/.openapi-generator/VERSION b/sdk/ts/.openapi-generator/VERSION new file mode 100644 index 0000000..6328c54 --- /dev/null +++ b/sdk/ts/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.17.0 diff --git a/sdk/ts/README.md b/sdk/ts/README.md new file mode 100644 index 0000000..188d4ff --- /dev/null +++ b/sdk/ts/README.md @@ -0,0 +1,196 @@ +# @glueops/autoglue-sdk@0.1.0 + +A TypeScript SDK client for the localhost API. + +## Usage + +First, install the SDK from npm. + +```bash +npm install @glueops/autoglue-sdk --save +``` + +Next, try it out. + +```ts +import { Configuration, AuthApi } from "@glueops/autoglue-sdk"; +import type { AuthCallbackRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const api = new AuthApi(); + + const body = { + // string | google|github + provider: provider_example, + } satisfies AuthCallbackRequest; + + try { + const data = await api.authCallback(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +## Documentation + +### API Endpoints + +All URIs are relative to _http://localhost:8080/api/v1_ + +| Class | Method | HTTP request | Description | +| -------------- | ------------------------------------------------------------- | --------------------------------------- | ----------------------------------------------- | +| _AuthApi_ | [**authCallback**](docs/AuthApi.md#authcallback) | **GET** /auth/{provider}/callback | Handle social login callback | +| _AuthApi_ | [**authStart**](docs/AuthApi.md#authstart) | **POST** /auth/{provider}/start | Begin social login | +| _AuthApi_ | [**getJWKS**](docs/AuthApi.md#getjwks) | **GET** /.well-known/jwks.json | Get JWKS | +| _AuthApi_ | [**logout**](docs/AuthApi.md#logout) | **POST** /auth/logout | Revoke refresh token family (logout everywhere) | +| _AuthApi_ | [**refresh**](docs/AuthApi.md#refresh) | **POST** /auth/refresh | Rotate refresh token | +| _MeApi_ | [**getMe**](docs/MeApi.md#getme) | **GET** /me | Get current user profile | +| _MeApi_ | [**updateMe**](docs/MeApi.md#updateme) | **PATCH** /me | Update current user profile | +| _MeAPIKeysApi_ | [**createUserAPIKey**](docs/MeAPIKeysApi.md#createuserapikey) | **POST** /me/api-keys | Create a new user API key | +| _MeAPIKeysApi_ | [**deleteUserAPIKey**](docs/MeAPIKeysApi.md#deleteuserapikey) | **DELETE** /me/api-keys/{id} | Delete a user API key | +| _MeAPIKeysApi_ | [**listUserAPIKeys**](docs/MeAPIKeysApi.md#listuserapikeys) | **GET** /me/api-keys | List my API keys | +| _OrgsApi_ | [**addOrUpdateMember**](docs/OrgsApi.md#addorupdatemember) | **POST** /orgs/{id}/members | Add or update a member (owner/admin) | +| _OrgsApi_ | [**createOrg**](docs/OrgsApi.md#createorg) | **POST** /orgs | Create organization | +| _OrgsApi_ | [**createOrgKey**](docs/OrgsApi.md#createorgkey) | **POST** /orgs/{id}/api-keys | Create org key/secret pair (owner/admin) | +| _OrgsApi_ | [**deleteOrg**](docs/OrgsApi.md#deleteorg) | **DELETE** /orgs/{id} | Delete organization (owner) | +| _OrgsApi_ | [**deleteOrgKey**](docs/OrgsApi.md#deleteorgkey) | **DELETE** /orgs/{id}/api-keys/{key_id} | Delete org key (owner/admin) | +| _OrgsApi_ | [**getOrg**](docs/OrgsApi.md#getorg) | **GET** /orgs/{id} | Get organization | +| _OrgsApi_ | [**listMembers**](docs/OrgsApi.md#listmembers) | **GET** /orgs/{id}/members | List members in org | +| _OrgsApi_ | [**listMyOrgs**](docs/OrgsApi.md#listmyorgs) | **GET** /orgs | List organizations I belong to | +| _OrgsApi_ | [**listOrgKeys**](docs/OrgsApi.md#listorgkeys) | **GET** /orgs/{id}/api-keys | List org-scoped API keys (no secrets) | +| _OrgsApi_ | [**removeMember**](docs/OrgsApi.md#removemember) | **DELETE** /orgs/{id}/members/{user_id} | Remove a member (owner/admin) | +| _OrgsApi_ | [**updateOrg**](docs/OrgsApi.md#updateorg) | **PATCH** /orgs/{id} | Update organization (owner/admin) | +| _ServersApi_ | [**createServer**](docs/ServersApi.md#createserver) | **POST** /servers | Create server (org scoped) | +| _ServersApi_ | [**deleteServer**](docs/ServersApi.md#deleteserver) | **DELETE** /servers/{id} | Delete server (org scoped) | +| _ServersApi_ | [**getServer**](docs/ServersApi.md#getserver) | **GET** /servers/{id} | Get server by ID (org scoped) | +| _ServersApi_ | [**listServers**](docs/ServersApi.md#listservers) | **GET** /servers | List servers (org scoped) | +| _ServersApi_ | [**updateServer**](docs/ServersApi.md#updateserver) | **PATCH** /servers/{id} | Update server (org scoped) | +| _SshApi_ | [**createSSHKey**](docs/SshApi.md#createsshkey) | **POST** /ssh | Create ssh keypair (org scoped) | +| _SshApi_ | [**deleteSSHKey**](docs/SshApi.md#deletesshkey) | **DELETE** /ssh/{id} | Delete ssh keypair (org scoped) | +| _SshApi_ | [**downloadSSHKey**](docs/SshApi.md#downloadsshkey) | **GET** /ssh/{id}/download | Download ssh key files by ID (org scoped) | +| _SshApi_ | [**getSSHKey**](docs/SshApi.md#getsshkey) | **GET** /ssh/{id} | Get ssh key by ID (org scoped) | +| _SshApi_ | [**listPublicSshKeys**](docs/SshApi.md#listpublicsshkeys) | **GET** /ssh | List ssh keys (org scoped) | +| _TaintsApi_ | [**createTaint**](docs/TaintsApi.md#createtaint) | **POST** /taints | Create node taint (org scoped) | +| _TaintsApi_ | [**deleteTaint**](docs/TaintsApi.md#deletetaint) | **DELETE** /taints/{id} | Delete taint (org scoped) | +| _TaintsApi_ | [**getTaint**](docs/TaintsApi.md#gettaint) | **GET** /taints/{id} | Get node taint by ID (org scoped) | +| _TaintsApi_ | [**listTaints**](docs/TaintsApi.md#listtaints) | **GET** /taints | List node pool taints (org scoped) | +| _TaintsApi_ | [**updateTaint**](docs/TaintsApi.md#updatetaint) | **PATCH** /taints/{id} | Update node taint (org scoped) | + +### Models + +- [DtoAuthStartResponse](docs/DtoAuthStartResponse.md) +- [DtoCreateSSHRequest](docs/DtoCreateSSHRequest.md) +- [DtoCreateServerRequest](docs/DtoCreateServerRequest.md) +- [DtoCreateTaintRequest](docs/DtoCreateTaintRequest.md) +- [DtoJWK](docs/DtoJWK.md) +- [DtoJWKS](docs/DtoJWKS.md) +- [DtoLogoutRequest](docs/DtoLogoutRequest.md) +- [DtoRefreshRequest](docs/DtoRefreshRequest.md) +- [DtoServerResponse](docs/DtoServerResponse.md) +- [DtoSshResponse](docs/DtoSshResponse.md) +- [DtoSshRevealResponse](docs/DtoSshRevealResponse.md) +- [DtoTaintResponse](docs/DtoTaintResponse.md) +- [DtoTokenPair](docs/DtoTokenPair.md) +- [DtoUpdateServerRequest](docs/DtoUpdateServerRequest.md) +- [DtoUpdateTaintRequest](docs/DtoUpdateTaintRequest.md) +- [HandlersCreateUserKeyRequest](docs/HandlersCreateUserKeyRequest.md) +- [HandlersMeResponse](docs/HandlersMeResponse.md) +- [HandlersMemberOut](docs/HandlersMemberOut.md) +- [HandlersMemberUpsertReq](docs/HandlersMemberUpsertReq.md) +- [HandlersOrgCreateReq](docs/HandlersOrgCreateReq.md) +- [HandlersOrgKeyCreateReq](docs/HandlersOrgKeyCreateReq.md) +- [HandlersOrgKeyCreateResp](docs/HandlersOrgKeyCreateResp.md) +- [HandlersOrgUpdateReq](docs/HandlersOrgUpdateReq.md) +- [HandlersUpdateMeRequest](docs/HandlersUpdateMeRequest.md) +- [HandlersUserAPIKeyOut](docs/HandlersUserAPIKeyOut.md) +- [ModelsAPIKey](docs/ModelsAPIKey.md) +- [ModelsOrganization](docs/ModelsOrganization.md) +- [ModelsUser](docs/ModelsUser.md) +- [ModelsUserEmail](docs/ModelsUserEmail.md) +- [UtilsErrorResponse](docs/UtilsErrorResponse.md) + +### Authorization + +Authentication schemes defined for the API: + + +#### ApiKeyAuth + +- **Type**: API key +- **API key parameter name**: `X-API-KEY` +- **Location**: HTTP header + + +#### BearerAuth + +- **Type**: API key +- **API key parameter name**: `Authorization` +- **Location**: HTTP header + + +#### OrgKeyAuth + +- **Type**: API key +- **API key parameter name**: `X-ORG-KEY` +- **Location**: HTTP header + + +#### OrgSecretAuth + +- **Type**: API key +- **API key parameter name**: `X-ORG-SECRET` +- **Location**: HTTP header + +## About + +This TypeScript SDK client supports the [Fetch API](https://fetch.spec.whatwg.org/) +and is automatically generated by the +[OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: `1.0` +- Package version: `0.1.0` +- Generator version: `7.17.0` +- Build package: `org.openapitools.codegen.languages.TypeScriptFetchClientCodegen` + +The generated npm module supports the following: + +- Environments + - Node.js + - Webpack + - Browserify +- Language levels + - ES5 - you must have a Promises/A+ library installed + - ES6 +- Module systems + - CommonJS + - ES6 module system + +## Development + +### Building + +To build the TypeScript source code, you need to have Node.js and npm installed. +After cloning the repository, navigate to the project directory and run: + +```bash +npm install +npm run build +``` + +### Publishing + +Once you've built the package, you can publish it to npm: + +```bash +npm publish +``` + +## License + +[]() diff --git a/sdk/ts/docs/AuthApi.md b/sdk/ts/docs/AuthApi.md new file mode 100644 index 0000000..c7a1c76 --- /dev/null +++ b/sdk/ts/docs/AuthApi.md @@ -0,0 +1,314 @@ +# AuthApi + +All URIs are relative to _http://localhost:8080/api/v1_ + +| Method | HTTP request | Description | +| ------------------------------------------- | --------------------------------- | ----------------------------------------------- | +| [**authCallback**](AuthApi.md#authcallback) | **GET** /auth/{provider}/callback | Handle social login callback | +| [**authStart**](AuthApi.md#authstart) | **POST** /auth/{provider}/start | Begin social login | +| [**getJWKS**](AuthApi.md#getjwks) | **GET** /.well-known/jwks.json | Get JWKS | +| [**logout**](AuthApi.md#logout) | **POST** /auth/logout | Revoke refresh token family (logout everywhere) | +| [**refresh**](AuthApi.md#refresh) | **POST** /auth/refresh | Rotate refresh token | + +## authCallback + +> DtoTokenPair authCallback(provider) + +Handle social login callback + +### Example + +```ts +import { Configuration, AuthApi } from "@glueops/autoglue-sdk"; +import type { AuthCallbackRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const api = new AuthApi(); + + const body = { + // string | google|github + provider: provider_example, + } satisfies AuthCallbackRequest; + + try { + const data = await api.authCallback(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------ | -------- | ----------- | ------ | ------------------------- | +| **provider** | `string` | google | github | [Defaults to `undefined`] | + +### Return type + +[**DtoTokenPair**](DtoTokenPair.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **200** | OK | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## authStart + +> DtoAuthStartResponse authStart(provider) + +Begin social login + +Returns provider authorization URL for the frontend to redirect + +### Example + +```ts +import { Configuration, AuthApi } from "@glueops/autoglue-sdk"; +import type { AuthStartRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const api = new AuthApi(); + + const body = { + // string | google|github + provider: provider_example, + } satisfies AuthStartRequest; + + try { + const data = await api.authStart(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------ | -------- | ----------- | ------ | ------------------------- | +| **provider** | `string` | google | github | [Defaults to `undefined`] | + +### Return type + +[**DtoAuthStartResponse**](DtoAuthStartResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **200** | OK | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## getJWKS + +> DtoJWKS getJWKS() + +Get JWKS + +Returns the JSON Web Key Set for token verification + +### Example + +```ts +import { Configuration, AuthApi } from "@glueops/autoglue-sdk"; +import type { GetJWKSRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const api = new AuthApi(); + + try { + const data = await api.getJWKS(); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**DtoJWKS**](DtoJWKS.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **200** | OK | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## logout + +> logout(body) + +Revoke refresh token family (logout everywhere) + +### Example + +```ts +import { + Configuration, + AuthApi, +} from '@glueops/autoglue-sdk'; +import type { LogoutRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const api = new AuthApi(); + + const body = { + // DtoLogoutRequest | Refresh token + body: ..., + } satisfies LogoutRequest; + + try { + const data = await api.logout(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------- | --------------------------------------- | ------------- | ----- | +| **body** | [DtoLogoutRequest](DtoLogoutRequest.md) | Refresh token | | + +### Return type + +`void` (Empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: Not defined + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **204** | No Content | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## refresh + +> DtoTokenPair refresh(body) + +Rotate refresh token + +### Example + +```ts +import { + Configuration, + AuthApi, +} from '@glueops/autoglue-sdk'; +import type { RefreshRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const api = new AuthApi(); + + const body = { + // DtoRefreshRequest | Refresh token + body: ..., + } satisfies RefreshRequest; + + try { + const data = await api.refresh(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------- | ----------------------------------------- | ------------- | ----- | +| **body** | [DtoRefreshRequest](DtoRefreshRequest.md) | Refresh token | | + +### Return type + +[**DtoTokenPair**](DtoTokenPair.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **200** | OK | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoAuthStartResponse.md b/sdk/ts/docs/DtoAuthStartResponse.md new file mode 100644 index 0000000..036366a --- /dev/null +++ b/sdk/ts/docs/DtoAuthStartResponse.md @@ -0,0 +1,30 @@ +# DtoAuthStartResponse + +## Properties + +| Name | Type | +| ---------- | ------ | +| `auth_url` | string | + +## Example + +```typescript +import type { DtoAuthStartResponse } from '@glueops/autoglue-sdk' + +// TODO: Update the object below with actual values +const example = { + "auth_url": https://accounts.google.com/o/oauth2/v2/auth?client_id=..., +} satisfies DtoAuthStartResponse + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoAuthStartResponse +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoCreateSSHRequest.md b/sdk/ts/docs/DtoCreateSSHRequest.md new file mode 100644 index 0000000..6a42f8c --- /dev/null +++ b/sdk/ts/docs/DtoCreateSSHRequest.md @@ -0,0 +1,36 @@ +# DtoCreateSSHRequest + +## Properties + +| Name | Type | +| --------- | ------ | +| `bits` | number | +| `comment` | string | +| `name` | string | +| `type` | string | + +## Example + +```typescript +import type { DtoCreateSSHRequest } from '@glueops/autoglue-sdk' + +// TODO: Update the object below with actual values +const example = { + "bits": null, + "comment": deploy@autoglue, + "name": null, + "type": null, +} satisfies DtoCreateSSHRequest + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoCreateSSHRequest +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoCreateServerRequest.md b/sdk/ts/docs/DtoCreateServerRequest.md new file mode 100644 index 0000000..375cb6d --- /dev/null +++ b/sdk/ts/docs/DtoCreateServerRequest.md @@ -0,0 +1,42 @@ +# DtoCreateServerRequest + +## Properties + +| Name | Type | +| -------------------- | ------ | +| `hostname` | string | +| `private_ip_address` | string | +| `public_ip_address` | string | +| `role` | string | +| `ssh_key_id` | string | +| `ssh_user` | string | +| `status` | string | + +## Example + +```typescript +import type { DtoCreateServerRequest } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + hostname: null, + private_ip_address: null, + public_ip_address: null, + role: master | worker | bastion, + ssh_key_id: null, + ssh_user: null, + status: pending | provisioning | ready | failed, +} satisfies DtoCreateServerRequest; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoCreateServerRequest; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoCreateTaintRequest.md b/sdk/ts/docs/DtoCreateTaintRequest.md new file mode 100644 index 0000000..f0e0011 --- /dev/null +++ b/sdk/ts/docs/DtoCreateTaintRequest.md @@ -0,0 +1,34 @@ +# DtoCreateTaintRequest + +## Properties + +| Name | Type | +| -------- | ------ | +| `effect` | string | +| `key` | string | +| `value` | string | + +## Example + +```typescript +import type { DtoCreateTaintRequest } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + effect: null, + key: null, + value: null, +} satisfies DtoCreateTaintRequest; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoCreateTaintRequest; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoJWK.md b/sdk/ts/docs/DtoJWK.md new file mode 100644 index 0000000..72be330 --- /dev/null +++ b/sdk/ts/docs/DtoJWK.md @@ -0,0 +1,42 @@ +# DtoJWK + +## Properties + +| Name | Type | +| ----- | ------ | +| `alg` | string | +| `e` | string | +| `kid` | string | +| `kty` | string | +| `n` | string | +| `use` | string | +| `x` | string | + +## Example + +```typescript +import type { DtoJWK } from '@glueops/autoglue-sdk' + +// TODO: Update the object below with actual values +const example = { + "alg": RS256, + "e": AQAB, + "kid": 7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345, + "kty": RSA, + "n": null, + "use": sig, + "x": null, +} satisfies DtoJWK + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoJWK +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoJWKS.md b/sdk/ts/docs/DtoJWKS.md new file mode 100644 index 0000000..b969b5a --- /dev/null +++ b/sdk/ts/docs/DtoJWKS.md @@ -0,0 +1,30 @@ +# DtoJWKS + +## Properties + +| Name | Type | +| ------ | -------------------------------- | +| `keys` | [Array<DtoJWK>](DtoJWK.md) | + +## Example + +```typescript +import type { DtoJWKS } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + keys: null, +} satisfies DtoJWKS; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoJWKS; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoLogoutRequest.md b/sdk/ts/docs/DtoLogoutRequest.md new file mode 100644 index 0000000..70d806a --- /dev/null +++ b/sdk/ts/docs/DtoLogoutRequest.md @@ -0,0 +1,30 @@ +# DtoLogoutRequest + +## Properties + +| Name | Type | +| --------------- | ------ | +| `refresh_token` | string | + +## Example + +```typescript +import type { DtoLogoutRequest } from '@glueops/autoglue-sdk' + +// TODO: Update the object below with actual values +const example = { + "refresh_token": m0l9o8rT3t0V8d3eFf..., +} satisfies DtoLogoutRequest + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoLogoutRequest +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoRefreshRequest.md b/sdk/ts/docs/DtoRefreshRequest.md new file mode 100644 index 0000000..d3d5b04 --- /dev/null +++ b/sdk/ts/docs/DtoRefreshRequest.md @@ -0,0 +1,30 @@ +# DtoRefreshRequest + +## Properties + +| Name | Type | +| --------------- | ------ | +| `refresh_token` | string | + +## Example + +```typescript +import type { DtoRefreshRequest } from '@glueops/autoglue-sdk' + +// TODO: Update the object below with actual values +const example = { + "refresh_token": m0l9o8rT3t0V8d3eFf..., +} satisfies DtoRefreshRequest + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoRefreshRequest +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoServerResponse.md b/sdk/ts/docs/DtoServerResponse.md new file mode 100644 index 0000000..7932f25 --- /dev/null +++ b/sdk/ts/docs/DtoServerResponse.md @@ -0,0 +1,50 @@ +# DtoServerResponse + +## Properties + +| Name | Type | +| -------------------- | ------ | +| `created_at` | string | +| `hostname` | string | +| `id` | string | +| `organization_id` | string | +| `private_ip_address` | string | +| `public_ip_address` | string | +| `role` | string | +| `ssh_key_id` | string | +| `ssh_user` | string | +| `status` | string | +| `updated_at` | string | + +## Example + +```typescript +import type { DtoServerResponse } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + created_at: null, + hostname: null, + id: null, + organization_id: null, + private_ip_address: null, + public_ip_address: null, + role: null, + ssh_key_id: null, + ssh_user: null, + status: null, + updated_at: null, +} satisfies DtoServerResponse; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoServerResponse; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoSshResponse.md b/sdk/ts/docs/DtoSshResponse.md new file mode 100644 index 0000000..a034b7f --- /dev/null +++ b/sdk/ts/docs/DtoSshResponse.md @@ -0,0 +1,42 @@ +# DtoSshResponse + +## Properties + +| Name | Type | +| ----------------- | ------ | +| `created_at` | string | +| `fingerprint` | string | +| `id` | string | +| `name` | string | +| `organization_id` | string | +| `public_key` | string | +| `updated_at` | string | + +## Example + +```typescript +import type { DtoSshResponse } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + created_at: null, + fingerprint: null, + id: null, + name: null, + organization_id: null, + public_key: null, + updated_at: null, +} satisfies DtoSshResponse; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoSshResponse; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoSshRevealResponse.md b/sdk/ts/docs/DtoSshRevealResponse.md new file mode 100644 index 0000000..1adfc46 --- /dev/null +++ b/sdk/ts/docs/DtoSshRevealResponse.md @@ -0,0 +1,44 @@ +# DtoSshRevealResponse + +## Properties + +| Name | Type | +| ----------------- | ------ | +| `created_at` | string | +| `fingerprint` | string | +| `id` | string | +| `name` | string | +| `organization_id` | string | +| `private_key` | string | +| `public_key` | string | +| `updated_at` | string | + +## Example + +```typescript +import type { DtoSshRevealResponse } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + created_at: null, + fingerprint: null, + id: null, + name: null, + organization_id: null, + private_key: null, + public_key: null, + updated_at: null, +} satisfies DtoSshRevealResponse; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoSshRevealResponse; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoTaintResponse.md b/sdk/ts/docs/DtoTaintResponse.md new file mode 100644 index 0000000..679febf --- /dev/null +++ b/sdk/ts/docs/DtoTaintResponse.md @@ -0,0 +1,36 @@ +# DtoTaintResponse + +## Properties + +| Name | Type | +| -------- | ------ | +| `effect` | string | +| `id` | string | +| `key` | string | +| `value` | string | + +## Example + +```typescript +import type { DtoTaintResponse } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + effect: null, + id: null, + key: null, + value: null, +} satisfies DtoTaintResponse; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoTaintResponse; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoTokenPair.md b/sdk/ts/docs/DtoTokenPair.md new file mode 100644 index 0000000..d3a7c95 --- /dev/null +++ b/sdk/ts/docs/DtoTokenPair.md @@ -0,0 +1,36 @@ +# DtoTokenPair + +## Properties + +| Name | Type | +| --------------- | ------ | +| `access_token` | string | +| `expires_in` | number | +| `refresh_token` | string | +| `token_type` | string | + +## Example + +```typescript +import type { DtoTokenPair } from '@glueops/autoglue-sdk' + +// TODO: Update the object below with actual values +const example = { + "access_token": eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij..., + "expires_in": 3600, + "refresh_token": m0l9o8rT3t0V8d3eFf...., + "token_type": Bearer, +} satisfies DtoTokenPair + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoTokenPair +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoUpdateServerRequest.md b/sdk/ts/docs/DtoUpdateServerRequest.md new file mode 100644 index 0000000..a851f92 --- /dev/null +++ b/sdk/ts/docs/DtoUpdateServerRequest.md @@ -0,0 +1,42 @@ +# DtoUpdateServerRequest + +## Properties + +| Name | Type | +| -------------------- | ------ | +| `hostname` | string | +| `private_ip_address` | string | +| `public_ip_address` | string | +| `role` | string | +| `ssh_key_id` | string | +| `ssh_user` | string | +| `status` | string | + +## Example + +```typescript +import type { DtoUpdateServerRequest } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + hostname: null, + private_ip_address: null, + public_ip_address: null, + role: master | worker | bastion, + ssh_key_id: null, + ssh_user: null, + status: pending | provisioning | ready | failed, +} satisfies DtoUpdateServerRequest; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoUpdateServerRequest; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/DtoUpdateTaintRequest.md b/sdk/ts/docs/DtoUpdateTaintRequest.md new file mode 100644 index 0000000..8de2857 --- /dev/null +++ b/sdk/ts/docs/DtoUpdateTaintRequest.md @@ -0,0 +1,34 @@ +# DtoUpdateTaintRequest + +## Properties + +| Name | Type | +| -------- | ------ | +| `effect` | string | +| `key` | string | +| `value` | string | + +## Example + +```typescript +import type { DtoUpdateTaintRequest } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + effect: null, + key: null, + value: null, +} satisfies DtoUpdateTaintRequest; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DtoUpdateTaintRequest; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersCreateUserKeyRequest.md b/sdk/ts/docs/HandlersCreateUserKeyRequest.md new file mode 100644 index 0000000..aa2f042 --- /dev/null +++ b/sdk/ts/docs/HandlersCreateUserKeyRequest.md @@ -0,0 +1,32 @@ +# HandlersCreateUserKeyRequest + +## Properties + +| Name | Type | +| ------------------ | ------ | +| `expires_in_hours` | number | +| `name` | string | + +## Example + +```typescript +import type { HandlersCreateUserKeyRequest } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + expires_in_hours: null, + name: null, +} satisfies HandlersCreateUserKeyRequest; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersCreateUserKeyRequest; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersMeResponse.md b/sdk/ts/docs/HandlersMeResponse.md new file mode 100644 index 0000000..33fd95c --- /dev/null +++ b/sdk/ts/docs/HandlersMeResponse.md @@ -0,0 +1,46 @@ +# HandlersMeResponse + +## Properties + +| Name | Type | +| --------------- | -------------------------------------------------------- | +| `avatar_url` | string | +| `created_at` | Date | +| `display_name` | string | +| `emails` | [Array<ModelsUserEmail>](ModelsUserEmail.md) | +| `id` | string | +| `is_disabled` | boolean | +| `organizations` | [Array<ModelsOrganization>](ModelsOrganization.md) | +| `primary_email` | string | +| `updated_at` | Date | + +## Example + +```typescript +import type { HandlersMeResponse } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + avatar_url: null, + created_at: null, + display_name: null, + emails: null, + id: null, + is_disabled: null, + organizations: null, + primary_email: null, + updated_at: null, +} satisfies HandlersMeResponse; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersMeResponse; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersMemberOut.md b/sdk/ts/docs/HandlersMemberOut.md new file mode 100644 index 0000000..69de153 --- /dev/null +++ b/sdk/ts/docs/HandlersMemberOut.md @@ -0,0 +1,34 @@ +# HandlersMemberOut + +## Properties + +| Name | Type | +| --------- | ------ | +| `email` | string | +| `role` | string | +| `user_id` | string | + +## Example + +```typescript +import type { HandlersMemberOut } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + email: null, + role: null, + user_id: null, +} satisfies HandlersMemberOut; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersMemberOut; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersMemberUpsertReq.md b/sdk/ts/docs/HandlersMemberUpsertReq.md new file mode 100644 index 0000000..df0de2f --- /dev/null +++ b/sdk/ts/docs/HandlersMemberUpsertReq.md @@ -0,0 +1,32 @@ +# HandlersMemberUpsertReq + +## Properties + +| Name | Type | +| --------- | ------ | +| `role` | string | +| `user_id` | string | + +## Example + +```typescript +import type { HandlersMemberUpsertReq } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + role: member, + user_id: null, +} satisfies HandlersMemberUpsertReq; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersMemberUpsertReq; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersOrgCreateReq.md b/sdk/ts/docs/HandlersOrgCreateReq.md new file mode 100644 index 0000000..b01d23a --- /dev/null +++ b/sdk/ts/docs/HandlersOrgCreateReq.md @@ -0,0 +1,32 @@ +# HandlersOrgCreateReq + +## Properties + +| Name | Type | +| -------- | ------ | +| `domain` | string | +| `name` | string | + +## Example + +```typescript +import type { HandlersOrgCreateReq } from '@glueops/autoglue-sdk' + +// TODO: Update the object below with actual values +const example = { + "domain": acme.com, + "name": Acme Corp, +} satisfies HandlersOrgCreateReq + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersOrgCreateReq +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersOrgKeyCreateReq.md b/sdk/ts/docs/HandlersOrgKeyCreateReq.md new file mode 100644 index 0000000..b612083 --- /dev/null +++ b/sdk/ts/docs/HandlersOrgKeyCreateReq.md @@ -0,0 +1,32 @@ +# HandlersOrgKeyCreateReq + +## Properties + +| Name | Type | +| ------------------ | ------ | +| `expires_in_hours` | number | +| `name` | string | + +## Example + +```typescript +import type { HandlersOrgKeyCreateReq } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + expires_in_hours: 720, + name: automation - bot, +} satisfies HandlersOrgKeyCreateReq; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersOrgKeyCreateReq; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersOrgKeyCreateResp.md b/sdk/ts/docs/HandlersOrgKeyCreateResp.md new file mode 100644 index 0000000..51321e7 --- /dev/null +++ b/sdk/ts/docs/HandlersOrgKeyCreateResp.md @@ -0,0 +1,42 @@ +# HandlersOrgKeyCreateResp + +## Properties + +| Name | Type | +| ------------ | ------ | +| `created_at` | string | +| `expires_at` | string | +| `id` | string | +| `name` | string | +| `org_key` | string | +| `org_secret` | string | +| `scope` | string | + +## Example + +```typescript +import type { HandlersOrgKeyCreateResp } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + created_at: null, + expires_at: null, + id: null, + name: null, + org_key: null, + org_secret: null, + scope: null, +} satisfies HandlersOrgKeyCreateResp; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersOrgKeyCreateResp; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersOrgUpdateReq.md b/sdk/ts/docs/HandlersOrgUpdateReq.md new file mode 100644 index 0000000..7eb3b58 --- /dev/null +++ b/sdk/ts/docs/HandlersOrgUpdateReq.md @@ -0,0 +1,32 @@ +# HandlersOrgUpdateReq + +## Properties + +| Name | Type | +| -------- | ------ | +| `domain` | string | +| `name` | string | + +## Example + +```typescript +import type { HandlersOrgUpdateReq } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + domain: null, + name: null, +} satisfies HandlersOrgUpdateReq; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersOrgUpdateReq; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersUpdateMeRequest.md b/sdk/ts/docs/HandlersUpdateMeRequest.md new file mode 100644 index 0000000..f5c45a6 --- /dev/null +++ b/sdk/ts/docs/HandlersUpdateMeRequest.md @@ -0,0 +1,30 @@ +# HandlersUpdateMeRequest + +## Properties + +| Name | Type | +| -------------- | ------ | +| `display_name` | string | + +## Example + +```typescript +import type { HandlersUpdateMeRequest } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + display_name: null, +} satisfies HandlersUpdateMeRequest; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersUpdateMeRequest; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/HandlersUserAPIKeyOut.md b/sdk/ts/docs/HandlersUserAPIKeyOut.md new file mode 100644 index 0000000..e245359 --- /dev/null +++ b/sdk/ts/docs/HandlersUserAPIKeyOut.md @@ -0,0 +1,42 @@ +# HandlersUserAPIKeyOut + +## Properties + +| Name | Type | +| -------------- | ------ | +| `created_at` | string | +| `expires_at` | string | +| `id` | string | +| `last_used_at` | string | +| `name` | string | +| `plain` | string | +| `scope` | string | + +## Example + +```typescript +import type { HandlersUserAPIKeyOut } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + created_at: null, + expires_at: null, + id: null, + last_used_at: null, + name: null, + plain: null, + scope: null, +} satisfies HandlersUserAPIKeyOut; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as HandlersUserAPIKeyOut; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/MeAPIKeysApi.md b/sdk/ts/docs/MeAPIKeysApi.md new file mode 100644 index 0000000..734d5a2 --- /dev/null +++ b/sdk/ts/docs/MeAPIKeysApi.md @@ -0,0 +1,203 @@ +# MeAPIKeysApi + +All URIs are relative to _http://localhost:8080/api/v1_ + +| Method | HTTP request | Description | +| -------------------------------------------------------- | ---------------------------- | ------------------------- | +| [**createUserAPIKey**](MeAPIKeysApi.md#createuserapikey) | **POST** /me/api-keys | Create a new user API key | +| [**deleteUserAPIKey**](MeAPIKeysApi.md#deleteuserapikey) | **DELETE** /me/api-keys/{id} | Delete a user API key | +| [**listUserAPIKeys**](MeAPIKeysApi.md#listuserapikeys) | **GET** /me/api-keys | List my API keys | + +## createUserAPIKey + +> HandlersUserAPIKeyOut createUserAPIKey(body) + +Create a new user API key + +Returns the plaintext key once. Store it securely on the client side. + +### Example + +```ts +import { + Configuration, + MeAPIKeysApi, +} from '@glueops/autoglue-sdk'; +import type { CreateUserAPIKeyRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: ApiKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new MeAPIKeysApi(config); + + const body = { + // HandlersCreateUserKeyRequest | Key options + body: ..., + } satisfies CreateUserAPIKeyRequest; + + try { + const data = await api.createUserAPIKey(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------- | --------------------------------------------------------------- | ----------- | ----- | +| **body** | [HandlersCreateUserKeyRequest](HandlersCreateUserKeyRequest.md) | Key options | | + +### Return type + +[**HandlersUserAPIKeyOut**](HandlersUserAPIKeyOut.md) + +### Authorization + +[ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **201** | Created | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## deleteUserAPIKey + +> deleteUserAPIKey(id) + +Delete a user API key + +### Example + +```ts +import { Configuration, MeAPIKeysApi } from "@glueops/autoglue-sdk"; +import type { DeleteUserAPIKeyRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new MeAPIKeysApi(config); + + const body = { + // string | Key ID (UUID) + id: id_example, + } satisfies DeleteUserAPIKeyRequest; + + try { + const data = await api.deleteUserAPIKey(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------ | -------- | ------------- | ------------------------- | +| **id** | `string` | Key ID (UUID) | [Defaults to `undefined`] | + +### Return type + +`void` (Empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **204** | No Content | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## listUserAPIKeys + +> Array<HandlersUserAPIKeyOut> listUserAPIKeys() + +List my API keys + +### Example + +```ts +import { Configuration, MeAPIKeysApi } from "@glueops/autoglue-sdk"; +import type { ListUserAPIKeysRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: ApiKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new MeAPIKeysApi(config); + + try { + const data = await api.listUserAPIKeys(); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**Array<HandlersUserAPIKeyOut>**](HandlersUserAPIKeyOut.md) + +### Authorization + +[ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **200** | OK | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/MeApi.md b/sdk/ts/docs/MeApi.md new file mode 100644 index 0000000..a649361 --- /dev/null +++ b/sdk/ts/docs/MeApi.md @@ -0,0 +1,136 @@ +# MeApi + +All URIs are relative to _http://localhost:8080/api/v1_ + +| Method | HTTP request | Description | +| --------------------------------- | ------------- | --------------------------- | +| [**getMe**](MeApi.md#getme) | **GET** /me | Get current user profile | +| [**updateMe**](MeApi.md#updateme) | **PATCH** /me | Update current user profile | + +## getMe + +> HandlersMeResponse getMe() + +Get current user profile + +### Example + +```ts +import { Configuration, MeApi } from "@glueops/autoglue-sdk"; +import type { GetMeRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: ApiKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new MeApi(config); + + try { + const data = await api.getMe(); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**HandlersMeResponse**](HandlersMeResponse.md) + +### Authorization + +[ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **200** | OK | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## updateMe + +> ModelsUser updateMe(body) + +Update current user profile + +### Example + +```ts +import { + Configuration, + MeApi, +} from '@glueops/autoglue-sdk'; +import type { UpdateMeRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: ApiKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new MeApi(config); + + const body = { + // HandlersUpdateMeRequest | Patch profile + body: ..., + } satisfies UpdateMeRequest; + + try { + const data = await api.updateMe(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------- | ----------------------------------------------------- | ------------- | ----- | +| **body** | [HandlersUpdateMeRequest](HandlersUpdateMeRequest.md) | Patch profile | | + +### Return type + +[**ModelsUser**](ModelsUser.md) + +### Authorization + +[ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------- | ---------------- | +| **200** | OK | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/ModelsAPIKey.md b/sdk/ts/docs/ModelsAPIKey.md new file mode 100644 index 0000000..e8a8ef9 --- /dev/null +++ b/sdk/ts/docs/ModelsAPIKey.md @@ -0,0 +1,50 @@ +# ModelsAPIKey + +## Properties + +| Name | Type | +| -------------- | ------- | +| `created_at` | Date | +| `expires_at` | Date | +| `id` | string | +| `last_used_at` | Date | +| `name` | string | +| `org_id` | string | +| `prefix` | string | +| `revoked` | boolean | +| `scope` | string | +| `updated_at` | Date | +| `user_id` | string | + +## Example + +```typescript +import type { ModelsAPIKey } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + created_at: null, + expires_at: null, + id: null, + last_used_at: null, + name: null, + org_id: null, + prefix: null, + revoked: null, + scope: null, + updated_at: null, + user_id: null, +} satisfies ModelsAPIKey; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as ModelsAPIKey; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/ModelsOrganization.md b/sdk/ts/docs/ModelsOrganization.md new file mode 100644 index 0000000..ef4c802 --- /dev/null +++ b/sdk/ts/docs/ModelsOrganization.md @@ -0,0 +1,38 @@ +# ModelsOrganization + +## Properties + +| Name | Type | +| ------------ | ------ | +| `created_at` | Date | +| `domain` | string | +| `id` | string | +| `name` | string | +| `updated_at` | Date | + +## Example + +```typescript +import type { ModelsOrganization } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + created_at: null, + domain: null, + id: null, + name: null, + updated_at: null, +} satisfies ModelsOrganization; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as ModelsOrganization; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/ModelsUser.md b/sdk/ts/docs/ModelsUser.md new file mode 100644 index 0000000..93e00d0 --- /dev/null +++ b/sdk/ts/docs/ModelsUser.md @@ -0,0 +1,42 @@ +# ModelsUser + +## Properties + +| Name | Type | +| --------------- | ------- | +| `avatar_url` | string | +| `created_at` | Date | +| `display_name` | string | +| `id` | string | +| `is_disabled` | boolean | +| `primary_email` | string | +| `updated_at` | Date | + +## Example + +```typescript +import type { ModelsUser } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + avatar_url: null, + created_at: null, + display_name: null, + id: null, + is_disabled: null, + primary_email: null, + updated_at: null, +} satisfies ModelsUser; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as ModelsUser; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/ModelsUserEmail.md b/sdk/ts/docs/ModelsUserEmail.md new file mode 100644 index 0000000..53e8b43 --- /dev/null +++ b/sdk/ts/docs/ModelsUserEmail.md @@ -0,0 +1,44 @@ +# ModelsUserEmail + +## Properties + +| Name | Type | +| ------------- | --------------------------- | +| `created_at` | Date | +| `email` | string | +| `id` | string | +| `is_primary` | boolean | +| `is_verified` | boolean | +| `updated_at` | Date | +| `user` | [ModelsUser](ModelsUser.md) | +| `user_id` | string | + +## Example + +```typescript +import type { ModelsUserEmail } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + created_at: null, + email: null, + id: null, + is_primary: null, + is_verified: null, + updated_at: null, + user: null, + user_id: null, +} satisfies ModelsUserEmail; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as ModelsUserEmail; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/OrgsApi.md b/sdk/ts/docs/OrgsApi.md new file mode 100644 index 0000000..acacf5c --- /dev/null +++ b/sdk/ts/docs/OrgsApi.md @@ -0,0 +1,757 @@ +# OrgsApi + +All URIs are relative to _http://localhost:8080/api/v1_ + +| Method | HTTP request | Description | +| ----------------------------------------------------- | --------------------------------------- | ---------------------------------------- | +| [**addOrUpdateMember**](OrgsApi.md#addorupdatemember) | **POST** /orgs/{id}/members | Add or update a member (owner/admin) | +| [**createOrg**](OrgsApi.md#createorg) | **POST** /orgs | Create organization | +| [**createOrgKey**](OrgsApi.md#createorgkey) | **POST** /orgs/{id}/api-keys | Create org key/secret pair (owner/admin) | +| [**deleteOrg**](OrgsApi.md#deleteorg) | **DELETE** /orgs/{id} | Delete organization (owner) | +| [**deleteOrgKey**](OrgsApi.md#deleteorgkey) | **DELETE** /orgs/{id}/api-keys/{key_id} | Delete org key (owner/admin) | +| [**getOrg**](OrgsApi.md#getorg) | **GET** /orgs/{id} | Get organization | +| [**listMembers**](OrgsApi.md#listmembers) | **GET** /orgs/{id}/members | List members in org | +| [**listMyOrgs**](OrgsApi.md#listmyorgs) | **GET** /orgs | List organizations I belong to | +| [**listOrgKeys**](OrgsApi.md#listorgkeys) | **GET** /orgs/{id}/api-keys | List org-scoped API keys (no secrets) | +| [**removeMember**](OrgsApi.md#removemember) | **DELETE** /orgs/{id}/members/{user_id} | Remove a member (owner/admin) | +| [**updateOrg**](OrgsApi.md#updateorg) | **PATCH** /orgs/{id} | Update organization (owner/admin) | + +## addOrUpdateMember + +> HandlersMemberOut addOrUpdateMember(id, body) + +Add or update a member (owner/admin) + +### Example + +```ts +import { + Configuration, + OrgsApi, +} from '@glueops/autoglue-sdk'; +import type { AddOrUpdateMemberRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + // HandlersMemberUpsertReq | User & role + body: ..., + } satisfies AddOrUpdateMemberRequest; + + try { + const data = await api.addOrUpdateMember(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------- | ----------------------------------------------------- | --------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | +| **body** | [HandlersMemberUpsertReq](HandlersMemberUpsertReq.md) | User & role | | + +### Return type + +[**HandlersMemberOut**](HandlersMemberOut.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## createOrg + +> ModelsOrganization createOrg(body) + +Create organization + +### Example + +```ts +import { + Configuration, + OrgsApi, +} from '@glueops/autoglue-sdk'; +import type { CreateOrgRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // HandlersOrgCreateReq | Org payload + body: ..., + } satisfies CreateOrgRequest; + + try { + const data = await api.createOrg(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------- | ----------------------------------------------- | ----------- | ----- | +| **body** | [HandlersOrgCreateReq](HandlersOrgCreateReq.md) | Org payload | | + +### Return type + +[**ModelsOrganization**](ModelsOrganization.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **201** | Created | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **409** | Conflict | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## createOrgKey + +> HandlersOrgKeyCreateResp createOrgKey(id, body) + +Create org key/secret pair (owner/admin) + +### Example + +```ts +import { + Configuration, + OrgsApi, +} from '@glueops/autoglue-sdk'; +import type { CreateOrgKeyRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + // HandlersOrgKeyCreateReq | Key name + optional expiry + body: ..., + } satisfies CreateOrgKeyRequest; + + try { + const data = await api.createOrgKey(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------- | ----------------------------------------------------- | -------------------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | +| **body** | [HandlersOrgKeyCreateReq](HandlersOrgKeyCreateReq.md) | Key name + optional expiry | | + +### Return type + +[**HandlersOrgKeyCreateResp**](HandlersOrgKeyCreateResp.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **201** | Created | - | +| **401** | Unauthorized | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## deleteOrg + +> deleteOrg(id) + +Delete organization (owner) + +### Example + +```ts +import { Configuration, OrgsApi } from "@glueops/autoglue-sdk"; +import type { DeleteOrgRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + } satisfies DeleteOrgRequest; + + try { + const data = await api.deleteOrg(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------ | -------- | ------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | + +### Return type + +`void` (Empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **204** | Deleted | - | +| **401** | Unauthorized | - | +| **404** | Not Found | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## deleteOrgKey + +> deleteOrgKey(id, keyId) + +Delete org key (owner/admin) + +### Example + +```ts +import { Configuration, OrgsApi } from "@glueops/autoglue-sdk"; +import type { DeleteOrgKeyRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + // string | Key ID (UUID) + keyId: keyId_example, + } satisfies DeleteOrgKeyRequest; + + try { + const data = await api.deleteOrgKey(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| --------- | -------- | ------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | +| **keyId** | `string` | Key ID (UUID) | [Defaults to `undefined`] | + +### Return type + +`void` (Empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **204** | Deleted | - | +| **401** | Unauthorized | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## getOrg + +> ModelsOrganization getOrg(id) + +Get organization + +### Example + +```ts +import { Configuration, OrgsApi } from "@glueops/autoglue-sdk"; +import type { GetOrgRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + } satisfies GetOrgRequest; + + try { + const data = await api.getOrg(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------ | -------- | ------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | + +### Return type + +[**ModelsOrganization**](ModelsOrganization.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | +| **404** | Not Found | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## listMembers + +> Array<HandlersMemberOut> listMembers(id) + +List members in org + +### Example + +```ts +import { Configuration, OrgsApi } from "@glueops/autoglue-sdk"; +import type { ListMembersRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + } satisfies ListMembersRequest; + + try { + const data = await api.listMembers(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------ | -------- | ------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | + +### Return type + +[**Array<HandlersMemberOut>**](HandlersMemberOut.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## listMyOrgs + +> Array<ModelsOrganization> listMyOrgs() + +List organizations I belong to + +### Example + +```ts +import { Configuration, OrgsApi } from "@glueops/autoglue-sdk"; +import type { ListMyOrgsRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + try { + const data = await api.listMyOrgs(); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**Array<ModelsOrganization>**](ModelsOrganization.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## listOrgKeys + +> Array<ModelsAPIKey> listOrgKeys(id) + +List org-scoped API keys (no secrets) + +### Example + +```ts +import { Configuration, OrgsApi } from "@glueops/autoglue-sdk"; +import type { ListOrgKeysRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + } satisfies ListOrgKeysRequest; + + try { + const data = await api.listOrgKeys(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------ | -------- | ------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | + +### Return type + +[**Array<ModelsAPIKey>**](ModelsAPIKey.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## removeMember + +> removeMember(id, userId) + +Remove a member (owner/admin) + +### Example + +```ts +import { Configuration, OrgsApi } from "@glueops/autoglue-sdk"; +import type { RemoveMemberRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + // string | User ID (UUID) + userId: userId_example, + } satisfies RemoveMemberRequest; + + try { + const data = await api.removeMember(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | -------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | +| **userId** | `string` | User ID (UUID) | [Defaults to `undefined`] | + +### Return type + +`void` (Empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **204** | Removed | - | +| **401** | Unauthorized | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## updateOrg + +> ModelsOrganization updateOrg(id, body) + +Update organization (owner/admin) + +### Example + +```ts +import { + Configuration, + OrgsApi, +} from '@glueops/autoglue-sdk'; +import type { UpdateOrgRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new OrgsApi(config); + + const body = { + // string | Org ID (UUID) + id: id_example, + // HandlersOrgUpdateReq | Update payload + body: ..., + } satisfies UpdateOrgRequest; + + try { + const data = await api.updateOrg(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------- | ----------------------------------------------- | -------------- | ------------------------- | +| **id** | `string` | Org ID (UUID) | [Defaults to `undefined`] | +| **body** | [HandlersOrgUpdateReq](HandlersOrgUpdateReq.md) | Update payload | | + +### Return type + +[**ModelsOrganization**](ModelsOrganization.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------ | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | +| **404** | Not Found | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/ServersApi.md b/sdk/ts/docs/ServersApi.md new file mode 100644 index 0000000..f297318 --- /dev/null +++ b/sdk/ts/docs/ServersApi.md @@ -0,0 +1,409 @@ +# ServersApi + +All URIs are relative to _http://localhost:8080/api/v1_ + +| Method | HTTP request | Description | +| ---------------------------------------------- | ------------------------ | ----------------------------- | +| [**createServer**](ServersApi.md#createserver) | **POST** /servers | Create server (org scoped) | +| [**deleteServer**](ServersApi.md#deleteserver) | **DELETE** /servers/{id} | Delete server (org scoped) | +| [**getServer**](ServersApi.md#getserver) | **GET** /servers/{id} | Get server by ID (org scoped) | +| [**listServers**](ServersApi.md#listservers) | **GET** /servers | List servers (org scoped) | +| [**updateServer**](ServersApi.md#updateserver) | **PATCH** /servers/{id} | Update server (org scoped) | + +## createServer + +> DtoServerResponse createServer(body, xOrgID) + +Create server (org scoped) + +Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org. + +### Example + +```ts +import { + Configuration, + ServersApi, +} from '@glueops/autoglue-sdk'; +import type { CreateServerRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new ServersApi(config); + + const body = { + // DtoCreateServerRequest | Server payload + body: ..., + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies CreateServerRequest; + + try { + const data = await api.createServer(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | --------------------------------------------------- | ----------------- | ------------------------------------ | +| **body** | [DtoCreateServerRequest](DtoCreateServerRequest.md) | Server payload | | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +[**DtoServerResponse**](DtoServerResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------------------------------------------------------------- | ---------------- | +| **201** | Created | - | +| **400** | invalid json / missing fields / invalid status / invalid ssh_key_id | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | create failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## deleteServer + +> string deleteServer(id, xOrgID) + +Delete server (org scoped) + +Permanently deletes the server. + +### Example + +```ts +import { Configuration, ServersApi } from "@glueops/autoglue-sdk"; +import type { DeleteServerRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new ServersApi(config); + + const body = { + // string | Server ID (UUID) + id: id_example, + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies DeleteServerRequest; + + try { + const data = await api.deleteServer(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | ----------------- | ------------------------------------ | +| **id** | `string` | Server ID (UUID) | [Defaults to `undefined`] | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +**string** + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------- | ---------------- | +| **204** | No Content | - | +| **400** | invalid id | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | delete failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## getServer + +> DtoServerResponse getServer(id, xOrgID) + +Get server by ID (org scoped) + +Returns one server in the given organization. + +### Example + +```ts +import { Configuration, ServersApi } from "@glueops/autoglue-sdk"; +import type { GetServerRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new ServersApi(config); + + const body = { + // string | Server ID (UUID) + id: id_example, + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies GetServerRequest; + + try { + const data = await api.getServer(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | ----------------- | ------------------------------------ | +| **id** | `string` | Server ID (UUID) | [Defaults to `undefined`] | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +[**DtoServerResponse**](DtoServerResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------- | ---------------- | +| **200** | OK | - | +| **400** | invalid id | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **404** | not found | - | +| **500** | fetch failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## listServers + +> Array<DtoServerResponse> listServers(xOrgID, status, role) + +List servers (org scoped) + +Returns servers for the organization in X-Org-ID. Optional filters: status, role. + +### Example + +```ts +import { Configuration, ServersApi } from "@glueops/autoglue-sdk"; +import type { ListServersRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new ServersApi(config); + + const body = { + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + // string | Filter by status (pending|provisioning|ready|failed) (optional) + status: status_example, + // string | Filter by role (optional) + role: role_example, + } satisfies ListServersRequest; + + try { + const data = await api.listServers(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | ------------------------- | ------------------------------------ | ----- | ------- | ------------------------------------ | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | +| **status** | `string` | Filter by status (pending | provisioning | ready | failed) | [Optional] [Defaults to `undefined`] | +| **role** | `string` | Filter by role | [Optional] [Defaults to `undefined`] | + +### Return type + +[**Array<DtoServerResponse>**](DtoServerResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ---------------------- | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | failed to list servers | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## updateServer + +> DtoServerResponse updateServer(id, body, xOrgID) + +Update server (org scoped) + +Partially update fields; changing ssh_key_id validates ownership. + +### Example + +```ts +import { + Configuration, + ServersApi, +} from '@glueops/autoglue-sdk'; +import type { UpdateServerRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new ServersApi(config); + + const body = { + // string | Server ID (UUID) + id: id_example, + // DtoUpdateServerRequest | Fields to update + body: ..., + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies UpdateServerRequest; + + try { + const data = await api.updateServer(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | --------------------------------------------------- | ----------------- | ------------------------------------ | +| **id** | `string` | Server ID (UUID) | [Defaults to `undefined`] | +| **body** | [DtoUpdateServerRequest](DtoUpdateServerRequest.md) | Fields to update | | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +[**DtoServerResponse**](DtoServerResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------------------------------------------------- | ---------------- | +| **200** | OK | - | +| **400** | invalid id / invalid json / invalid status / invalid ssh_key_id | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **404** | not found | - | +| **500** | update failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/SshApi.md b/sdk/ts/docs/SshApi.md new file mode 100644 index 0000000..f09dc1b --- /dev/null +++ b/sdk/ts/docs/SshApi.md @@ -0,0 +1,403 @@ +# SshApi + +All URIs are relative to _http://localhost:8080/api/v1_ + +| Method | HTTP request | Description | +| ---------------------------------------------------- | -------------------------- | ----------------------------------------- | +| [**createSSHKey**](SshApi.md#createsshkey) | **POST** /ssh | Create ssh keypair (org scoped) | +| [**deleteSSHKey**](SshApi.md#deletesshkey) | **DELETE** /ssh/{id} | Delete ssh keypair (org scoped) | +| [**downloadSSHKey**](SshApi.md#downloadsshkey) | **GET** /ssh/{id}/download | Download ssh key files by ID (org scoped) | +| [**getSSHKey**](SshApi.md#getsshkey) | **GET** /ssh/{id} | Get ssh key by ID (org scoped) | +| [**listPublicSshKeys**](SshApi.md#listpublicsshkeys) | **GET** /ssh | List ssh keys (org scoped) | + +## createSSHKey + +> DtoSshResponse createSSHKey(body, xOrgID) + +Create ssh keypair (org scoped) + +Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits. + +### Example + +```ts +import { + Configuration, + SshApi, +} from '@glueops/autoglue-sdk'; +import type { CreateSSHKeyRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new SshApi(config); + + const body = { + // DtoCreateSSHRequest | Key generation options + body: ..., + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies CreateSSHKeyRequest; + + try { + const data = await api.createSSHKey(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | --------------------------------------------- | ---------------------- | ------------------------------------ | +| **body** | [DtoCreateSSHRequest](DtoCreateSSHRequest.md) | Key generation options | | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +[**DtoSshResponse**](DtoSshResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------------- | ---------------- | +| **201** | Created | - | +| **400** | invalid json / invalid bits | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | generation/create failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## deleteSSHKey + +> string deleteSSHKey(id, xOrgID) + +Delete ssh keypair (org scoped) + +Permanently deletes a keypair. + +### Example + +```ts +import { Configuration, SshApi } from "@glueops/autoglue-sdk"; +import type { DeleteSSHKeyRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new SshApi(config); + + const body = { + // string | SSH Key ID (UUID) + id: id_example, + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies DeleteSSHKeyRequest; + + try { + const data = await api.deleteSSHKey(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | ----------------- | ------------------------------------ | +| **id** | `string` | SSH Key ID (UUID) | [Defaults to `undefined`] | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +**string** + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------- | ---------------- | +| **204** | No Content | - | +| **400** | invalid id | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | delete failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## downloadSSHKey + +> string downloadSSHKey(xOrgID, id, part) + +Download ssh key files by ID (org scoped) + +Download `part=public|private|both` of the keypair. `both` returns a zip file. + +### Example + +```ts +import { Configuration, SshApi } from "@glueops/autoglue-sdk"; +import type { DownloadSSHKeyRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new SshApi(config); + + const body = { + // string | Organization UUID + xOrgID: xOrgID_example, + // string | SSH Key ID (UUID) + id: id_example, + // 'public' | 'private' | 'both' | Which part to download + part: part_example, + } satisfies DownloadSSHKeyRequest; + + try { + const data = await api.downloadSSHKey(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | --------------------------- | ---------------------- | ------------------------------------------------------- | +| **xOrgID** | `string` | Organization UUID | [Defaults to `undefined`] | +| **id** | `string` | SSH Key ID (UUID) | [Defaults to `undefined`] | +| **part** | `public`, `private`, `both` | Which part to download | [Defaults to `undefined`] [Enum: public, private, both] | + +### Return type + +**string** + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------------------- | ---------------- | +| **200** | file content | - | +| **400** | invalid id / invalid part | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **404** | not found | - | +| **500** | download failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## getSSHKey + +> DtoSshRevealResponse getSSHKey(id, xOrgID, reveal) + +Get ssh key by ID (org scoped) + +Returns public key fields. Append `?reveal=true` to include the private key PEM. + +### Example + +```ts +import { Configuration, SshApi } from "@glueops/autoglue-sdk"; +import type { GetSSHKeyRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new SshApi(config); + + const body = { + // string | SSH Key ID (UUID) + id: id_example, + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + // boolean | Reveal private key PEM (optional) + reveal: true, + } satisfies GetSSHKeyRequest; + + try { + const data = await api.getSSHKey(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | --------- | ---------------------- | ------------------------------------ | +| **id** | `string` | SSH Key ID (UUID) | [Defaults to `undefined`] | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | +| **reveal** | `boolean` | Reveal private key PEM | [Optional] [Defaults to `undefined`] | + +### Return type + +[**DtoSshRevealResponse**](DtoSshRevealResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------- | ---------------- | +| **200** | When reveal=true | - | +| **400** | invalid id | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **404** | not found | - | +| **500** | fetch failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## listPublicSshKeys + +> Array<DtoSshResponse> listPublicSshKeys(xOrgID) + +List ssh keys (org scoped) + +Returns ssh keys for the organization in X-Org-ID. + +### Example + +```ts +import { Configuration, SshApi } from "@glueops/autoglue-sdk"; +import type { ListPublicSshKeysRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new SshApi(config); + + const body = { + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies ListPublicSshKeysRequest; + + try { + const data = await api.listPublicSshKeys(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | ----------------- | ------------------------------------ | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +[**Array<DtoSshResponse>**](DtoSshResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------- | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | failed to list keys | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/TaintsApi.md b/sdk/ts/docs/TaintsApi.md new file mode 100644 index 0000000..00f2f59 --- /dev/null +++ b/sdk/ts/docs/TaintsApi.md @@ -0,0 +1,410 @@ +# TaintsApi + +All URIs are relative to _http://localhost:8080/api/v1_ + +| Method | HTTP request | Description | +| ------------------------------------------- | ----------------------- | ---------------------------------- | +| [**createTaint**](TaintsApi.md#createtaint) | **POST** /taints | Create node taint (org scoped) | +| [**deleteTaint**](TaintsApi.md#deletetaint) | **DELETE** /taints/{id} | Delete taint (org scoped) | +| [**getTaint**](TaintsApi.md#gettaint) | **GET** /taints/{id} | Get node taint by ID (org scoped) | +| [**listTaints**](TaintsApi.md#listtaints) | **GET** /taints | List node pool taints (org scoped) | +| [**updateTaint**](TaintsApi.md#updatetaint) | **PATCH** /taints/{id} | Update node taint (org scoped) | + +## createTaint + +> DtoTaintResponse createTaint(body, xOrgID) + +Create node taint (org scoped) + +Creates a taint. + +### Example + +```ts +import { + Configuration, + TaintsApi, +} from '@glueops/autoglue-sdk'; +import type { CreateTaintRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new TaintsApi(config); + + const body = { + // DtoCreateTaintRequest | Taint payload + body: ..., + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies CreateTaintRequest; + + try { + const data = await api.createTaint(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | ------------------------------------------------- | ----------------- | ------------------------------------ | +| **body** | [DtoCreateTaintRequest](DtoCreateTaintRequest.md) | Taint payload | | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +[**DtoTaintResponse**](DtoTaintResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ----------------------------------------------------- | ---------------- | +| **201** | Created | - | +| **400** | invalid json / missing fields / invalid node_pool_ids | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | create failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## deleteTaint + +> string deleteTaint(id, xOrgID) + +Delete taint (org scoped) + +Permanently deletes the taint. + +### Example + +```ts +import { Configuration, TaintsApi } from "@glueops/autoglue-sdk"; +import type { DeleteTaintRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new TaintsApi(config); + + const body = { + // string | Node Taint ID (UUID) + id: id_example, + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies DeleteTaintRequest; + + try { + const data = await api.deleteTaint(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | -------------------- | ------------------------------------ | +| **id** | `string` | Node Taint ID (UUID) | [Defaults to `undefined`] | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +**string** + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------- | ---------------- | +| **204** | No Content | - | +| **400** | invalid id | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | delete failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## getTaint + +> DtoTaintResponse getTaint(id, xOrgID) + +Get node taint by ID (org scoped) + +### Example + +```ts +import { Configuration, TaintsApi } from "@glueops/autoglue-sdk"; +import type { GetTaintRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new TaintsApi(config); + + const body = { + // string | Node Taint ID (UUID) + id: id_example, + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies GetTaintRequest; + + try { + const data = await api.getTaint(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | -------------------- | ------------------------------------ | +| **id** | `string` | Node Taint ID (UUID) | [Defaults to `undefined`] | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +[**DtoTaintResponse**](DtoTaintResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | --------------------- | ---------------- | +| **200** | OK | - | +| **400** | invalid id | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **404** | not found | - | +| **500** | fetch failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## listTaints + +> Array<DtoTaintResponse> listTaints(xOrgID, key, value, q) + +List node pool taints (org scoped) + +Returns node taints for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools. + +### Example + +```ts +import { Configuration, TaintsApi } from "@glueops/autoglue-sdk"; +import type { ListTaintsRequest } from "@glueops/autoglue-sdk"; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new TaintsApi(config); + + const body = { + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + // string | Exact key (optional) + key: key_example, + // string | Exact value (optional) + value: value_example, + // string | key contains (case-insensitive) (optional) + q: q_example, + } satisfies ListTaintsRequest; + + try { + const data = await api.listTaints(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | -------- | ------------------------------- | ------------------------------------ | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | +| **key** | `string` | Exact key | [Optional] [Defaults to `undefined`] | +| **value** | `string` | Exact value | [Optional] [Defaults to `undefined`] | +| **q** | `string` | key contains (case-insensitive) | [Optional] [Defaults to `undefined`] | + +### Return type + +[**Array<DtoTaintResponse>**](DtoTaintResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | -------------------------- | ---------------- | +| **200** | OK | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **500** | failed to list node taints | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + +## updateTaint + +> DtoTaintResponse updateTaint(id, body, xOrgID) + +Update node taint (org scoped) + +Partially update taint fields. + +### Example + +```ts +import { + Configuration, + TaintsApi, +} from '@glueops/autoglue-sdk'; +import type { UpdateTaintRequest } from '@glueops/autoglue-sdk'; + +async function example() { + console.log("🚀 Testing @glueops/autoglue-sdk SDK..."); + const config = new Configuration({ + // To configure API key authorization: OrgKeyAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: OrgSecretAuth + apiKey: "YOUR API KEY", + // To configure API key authorization: BearerAuth + apiKey: "YOUR API KEY", + }); + const api = new TaintsApi(config); + + const body = { + // string | Node Taint ID (UUID) + id: id_example, + // DtoUpdateTaintRequest | Fields to update + body: ..., + // string | Organization UUID (optional) + xOrgID: xOrgID_example, + } satisfies UpdateTaintRequest; + + try { + const data = await api.updateTaint(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + +| Name | Type | Description | Notes | +| ---------- | ------------------------------------------------- | -------------------- | ------------------------------------ | +| **id** | `string` | Node Taint ID (UUID) | [Defaults to `undefined`] | +| **body** | [DtoUpdateTaintRequest](DtoUpdateTaintRequest.md) | Fields to update | | +| **xOrgID** | `string` | Organization UUID | [Optional] [Defaults to `undefined`] | + +### Return type + +[**DtoTaintResponse**](DtoTaintResponse.md) + +### Authorization + +[OrgKeyAuth](../README.md#OrgKeyAuth), [OrgSecretAuth](../README.md#OrgSecretAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + +### HTTP response details + +| Status code | Description | Response headers | +| ----------- | ------------------------- | ---------------- | +| **200** | OK | - | +| **400** | invalid id / invalid json | - | +| **401** | Unauthorized | - | +| **403** | organization required | - | +| **404** | not found | - | +| **500** | update failed | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/docs/UtilsErrorResponse.md b/sdk/ts/docs/UtilsErrorResponse.md new file mode 100644 index 0000000..8809f4a --- /dev/null +++ b/sdk/ts/docs/UtilsErrorResponse.md @@ -0,0 +1,32 @@ +# UtilsErrorResponse + +## Properties + +| Name | Type | +| --------- | ------ | +| `code` | string | +| `message` | string | + +## Example + +```typescript +import type { UtilsErrorResponse } from "@glueops/autoglue-sdk"; + +// TODO: Update the object below with actual values +const example = { + code: null, + message: null, +} satisfies UtilsErrorResponse; + +console.log(example); + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example); +console.log(exampleJSON); + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as UtilsErrorResponse; +console.log(exampleParsed); +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) diff --git a/sdk/ts/package.json b/sdk/ts/package.json new file mode 100644 index 0000000..228f863 --- /dev/null +++ b/sdk/ts/package.json @@ -0,0 +1,21 @@ +{ + "name": "@glueops/autoglue-sdk", + "version": "0.1.0", + "description": "OpenAPI client for @glueops/autoglue-sdk", + "author": "OpenAPI-Generator", + "repository": { + "type": "git", + "url": "https://github.com/GIT_USER_ID/GIT_REPO_ID.git" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "module": "./dist/esm/index.js", + "sideEffects": false, + "scripts": { + "build": "tsc && tsc -p tsconfig.esm.json", + "prepare": "npm run build" + }, + "devDependencies": { + "typescript": "^4.0 || ^5.0" + } +} diff --git a/sdk/ts/src/apis/AuthApi.ts b/sdk/ts/src/apis/AuthApi.ts new file mode 100644 index 0000000..4d712be --- /dev/null +++ b/sdk/ts/src/apis/AuthApi.ts @@ -0,0 +1,294 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from "../runtime"; +import type { + DtoAuthStartResponse, + DtoJWKS, + DtoLogoutRequest, + DtoRefreshRequest, + DtoTokenPair, +} from "../models/index"; +import { + DtoAuthStartResponseFromJSON, + DtoAuthStartResponseToJSON, + DtoJWKSFromJSON, + DtoJWKSToJSON, + DtoLogoutRequestFromJSON, + DtoLogoutRequestToJSON, + DtoRefreshRequestFromJSON, + DtoRefreshRequestToJSON, + DtoTokenPairFromJSON, + DtoTokenPairToJSON, +} from "../models/index"; + +export interface AuthCallbackRequest { + provider: string; +} + +export interface AuthStartRequest { + provider: string; +} + +export interface LogoutRequest { + body: DtoLogoutRequest; +} + +export interface RefreshRequest { + body: DtoRefreshRequest; +} + +/** + * + */ +export class AuthApi extends runtime.BaseAPI { + /** + * Handle social login callback + */ + async authCallbackRaw( + requestParameters: AuthCallbackRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["provider"] == null) { + throw new runtime.RequiredError( + "provider", + 'Required parameter "provider" was null or undefined when calling authCallback().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + let urlPath = `/auth/{provider}/callback`; + urlPath = urlPath.replace( + `{${"provider"}}`, + encodeURIComponent(String(requestParameters["provider"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoTokenPairFromJSON(jsonValue), + ); + } + + /** + * Handle social login callback + */ + async authCallback( + requestParameters: AuthCallbackRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.authCallbackRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Returns provider authorization URL for the frontend to redirect + * Begin social login + */ + async authStartRaw( + requestParameters: AuthStartRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["provider"] == null) { + throw new runtime.RequiredError( + "provider", + 'Required parameter "provider" was null or undefined when calling authStart().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + let urlPath = `/auth/{provider}/start`; + urlPath = urlPath.replace( + `{${"provider"}}`, + encodeURIComponent(String(requestParameters["provider"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoAuthStartResponseFromJSON(jsonValue), + ); + } + + /** + * Returns provider authorization URL for the frontend to redirect + * Begin social login + */ + async authStart( + requestParameters: AuthStartRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.authStartRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Returns the JSON Web Key Set for token verification + * Get JWKS + */ + async getJWKSRaw( + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + let urlPath = `/.well-known/jwks.json`; + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoJWKSFromJSON(jsonValue), + ); + } + + /** + * Returns the JSON Web Key Set for token verification + * Get JWKS + */ + async getJWKS( + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.getJWKSRaw(initOverrides); + return await response.value(); + } + + /** + * Revoke refresh token family (logout everywhere) + */ + async logoutRaw( + requestParameters: LogoutRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling logout().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + let urlPath = `/auth/logout`; + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: DtoLogoutRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.VoidApiResponse(response); + } + + /** + * Revoke refresh token family (logout everywhere) + */ + async logout( + requestParameters: LogoutRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + await this.logoutRaw(requestParameters, initOverrides); + } + + /** + * Rotate refresh token + */ + async refreshRaw( + requestParameters: RefreshRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling refresh().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + let urlPath = `/auth/refresh`; + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: DtoRefreshRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoTokenPairFromJSON(jsonValue), + ); + } + + /** + * Rotate refresh token + */ + async refresh( + requestParameters: RefreshRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.refreshRaw(requestParameters, initOverrides); + return await response.value(); + } +} diff --git a/sdk/ts/src/apis/MeAPIKeysApi.ts b/sdk/ts/src/apis/MeAPIKeysApi.ts new file mode 100644 index 0000000..3117f29 --- /dev/null +++ b/sdk/ts/src/apis/MeAPIKeysApi.ts @@ -0,0 +1,201 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from "../runtime"; +import type { + HandlersCreateUserKeyRequest, + HandlersUserAPIKeyOut, +} from "../models/index"; +import { + HandlersCreateUserKeyRequestFromJSON, + HandlersCreateUserKeyRequestToJSON, + HandlersUserAPIKeyOutFromJSON, + HandlersUserAPIKeyOutToJSON, +} from "../models/index"; + +export interface CreateUserAPIKeyRequest { + body: HandlersCreateUserKeyRequest; +} + +export interface DeleteUserAPIKeyRequest { + id: string; +} + +/** + * + */ +export class MeAPIKeysApi extends runtime.BaseAPI { + /** + * Returns the plaintext key once. Store it securely on the client side. + * Create a new user API key + */ + async createUserAPIKeyRaw( + requestParameters: CreateUserAPIKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling createUserAPIKey().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-API-KEY"] = + await this.configuration.apiKey("X-API-KEY"); // ApiKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/me/api-keys`; + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: HandlersCreateUserKeyRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + HandlersUserAPIKeyOutFromJSON(jsonValue), + ); + } + + /** + * Returns the plaintext key once. Store it securely on the client side. + * Create a new user API key + */ + async createUserAPIKey( + requestParameters: CreateUserAPIKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.createUserAPIKeyRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Delete a user API key + */ + async deleteUserAPIKeyRaw( + requestParameters: DeleteUserAPIKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling deleteUserAPIKey().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/me/api-keys/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "DELETE", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.VoidApiResponse(response); + } + + /** + * Delete a user API key + */ + async deleteUserAPIKey( + requestParameters: DeleteUserAPIKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + await this.deleteUserAPIKeyRaw(requestParameters, initOverrides); + } + + /** + * List my API keys + */ + async listUserAPIKeysRaw( + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-API-KEY"] = + await this.configuration.apiKey("X-API-KEY"); // ApiKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/me/api-keys`; + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + jsonValue.map(HandlersUserAPIKeyOutFromJSON), + ); + } + + /** + * List my API keys + */ + async listUserAPIKeys( + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const response = await this.listUserAPIKeysRaw(initOverrides); + return await response.value(); + } +} diff --git a/sdk/ts/src/apis/MeApi.ts b/sdk/ts/src/apis/MeApi.ts new file mode 100644 index 0000000..f04e389 --- /dev/null +++ b/sdk/ts/src/apis/MeApi.ts @@ -0,0 +1,143 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from "../runtime"; +import type { + HandlersMeResponse, + HandlersUpdateMeRequest, + ModelsUser, +} from "../models/index"; +import { + HandlersMeResponseFromJSON, + HandlersMeResponseToJSON, + HandlersUpdateMeRequestFromJSON, + HandlersUpdateMeRequestToJSON, + ModelsUserFromJSON, + ModelsUserToJSON, +} from "../models/index"; + +export interface UpdateMeRequest { + body: HandlersUpdateMeRequest; +} + +/** + * + */ +export class MeApi extends runtime.BaseAPI { + /** + * Get current user profile + */ + async getMeRaw( + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-API-KEY"] = + await this.configuration.apiKey("X-API-KEY"); // ApiKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/me`; + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + HandlersMeResponseFromJSON(jsonValue), + ); + } + + /** + * Get current user profile + */ + async getMe( + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.getMeRaw(initOverrides); + return await response.value(); + } + + /** + * Update current user profile + */ + async updateMeRaw( + requestParameters: UpdateMeRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling updateMe().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-API-KEY"] = + await this.configuration.apiKey("X-API-KEY"); // ApiKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/me`; + + const response = await this.request( + { + path: urlPath, + method: "PATCH", + headers: headerParameters, + query: queryParameters, + body: HandlersUpdateMeRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + ModelsUserFromJSON(jsonValue), + ); + } + + /** + * Update current user profile + */ + async updateMe( + requestParameters: UpdateMeRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.updateMeRaw(requestParameters, initOverrides); + return await response.value(); + } +} diff --git a/sdk/ts/src/apis/OrgsApi.ts b/sdk/ts/src/apis/OrgsApi.ts new file mode 100644 index 0000000..289f507 --- /dev/null +++ b/sdk/ts/src/apis/OrgsApi.ts @@ -0,0 +1,742 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from "../runtime"; +import type { + HandlersMemberOut, + HandlersMemberUpsertReq, + HandlersOrgCreateReq, + HandlersOrgKeyCreateReq, + HandlersOrgKeyCreateResp, + HandlersOrgUpdateReq, + ModelsAPIKey, + ModelsOrganization, + UtilsErrorResponse, +} from "../models/index"; +import { + HandlersMemberOutFromJSON, + HandlersMemberOutToJSON, + HandlersMemberUpsertReqFromJSON, + HandlersMemberUpsertReqToJSON, + HandlersOrgCreateReqFromJSON, + HandlersOrgCreateReqToJSON, + HandlersOrgKeyCreateReqFromJSON, + HandlersOrgKeyCreateReqToJSON, + HandlersOrgKeyCreateRespFromJSON, + HandlersOrgKeyCreateRespToJSON, + HandlersOrgUpdateReqFromJSON, + HandlersOrgUpdateReqToJSON, + ModelsAPIKeyFromJSON, + ModelsAPIKeyToJSON, + ModelsOrganizationFromJSON, + ModelsOrganizationToJSON, + UtilsErrorResponseFromJSON, + UtilsErrorResponseToJSON, +} from "../models/index"; + +export interface AddOrUpdateMemberRequest { + id: string; + body: HandlersMemberUpsertReq; +} + +export interface CreateOrgRequest { + body: HandlersOrgCreateReq; +} + +export interface CreateOrgKeyRequest { + id: string; + body: HandlersOrgKeyCreateReq; +} + +export interface DeleteOrgRequest { + id: string; +} + +export interface DeleteOrgKeyRequest { + id: string; + keyId: string; +} + +export interface GetOrgRequest { + id: string; +} + +export interface ListMembersRequest { + id: string; +} + +export interface ListOrgKeysRequest { + id: string; +} + +export interface RemoveMemberRequest { + id: string; + userId: string; +} + +export interface UpdateOrgRequest { + id: string; + body: HandlersOrgUpdateReq; +} + +/** + * + */ +export class OrgsApi extends runtime.BaseAPI { + /** + * Add or update a member (owner/admin) + */ + async addOrUpdateMemberRaw( + requestParameters: AddOrUpdateMemberRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling addOrUpdateMember().', + ); + } + + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling addOrUpdateMember().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}/members`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: HandlersMemberUpsertReqToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + HandlersMemberOutFromJSON(jsonValue), + ); + } + + /** + * Add or update a member (owner/admin) + */ + async addOrUpdateMember( + requestParameters: AddOrUpdateMemberRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.addOrUpdateMemberRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Create organization + */ + async createOrgRaw( + requestParameters: CreateOrgRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling createOrg().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs`; + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: HandlersOrgCreateReqToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + ModelsOrganizationFromJSON(jsonValue), + ); + } + + /** + * Create organization + */ + async createOrg( + requestParameters: CreateOrgRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.createOrgRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Create org key/secret pair (owner/admin) + */ + async createOrgKeyRaw( + requestParameters: CreateOrgKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling createOrgKey().', + ); + } + + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling createOrgKey().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}/api-keys`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: HandlersOrgKeyCreateReqToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + HandlersOrgKeyCreateRespFromJSON(jsonValue), + ); + } + + /** + * Create org key/secret pair (owner/admin) + */ + async createOrgKey( + requestParameters: CreateOrgKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.createOrgKeyRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Delete organization (owner) + */ + async deleteOrgRaw( + requestParameters: DeleteOrgRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling deleteOrg().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "DELETE", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.VoidApiResponse(response); + } + + /** + * Delete organization (owner) + */ + async deleteOrg( + requestParameters: DeleteOrgRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + await this.deleteOrgRaw(requestParameters, initOverrides); + } + + /** + * Delete org key (owner/admin) + */ + async deleteOrgKeyRaw( + requestParameters: DeleteOrgKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling deleteOrgKey().', + ); + } + + if (requestParameters["keyId"] == null) { + throw new runtime.RequiredError( + "keyId", + 'Required parameter "keyId" was null or undefined when calling deleteOrgKey().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}/api-keys/{key_id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + urlPath = urlPath.replace( + `{${"key_id"}}`, + encodeURIComponent(String(requestParameters["keyId"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "DELETE", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.VoidApiResponse(response); + } + + /** + * Delete org key (owner/admin) + */ + async deleteOrgKey( + requestParameters: DeleteOrgKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + await this.deleteOrgKeyRaw(requestParameters, initOverrides); + } + + /** + * Get organization + */ + async getOrgRaw( + requestParameters: GetOrgRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling getOrg().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + ModelsOrganizationFromJSON(jsonValue), + ); + } + + /** + * Get organization + */ + async getOrg( + requestParameters: GetOrgRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.getOrgRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * List members in org + */ + async listMembersRaw( + requestParameters: ListMembersRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise>> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling listMembers().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}/members`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + jsonValue.map(HandlersMemberOutFromJSON), + ); + } + + /** + * List members in org + */ + async listMembers( + requestParameters: ListMembersRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const response = await this.listMembersRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * List organizations I belong to + */ + async listMyOrgsRaw( + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs`; + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + jsonValue.map(ModelsOrganizationFromJSON), + ); + } + + /** + * List organizations I belong to + */ + async listMyOrgs( + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const response = await this.listMyOrgsRaw(initOverrides); + return await response.value(); + } + + /** + * List org-scoped API keys (no secrets) + */ + async listOrgKeysRaw( + requestParameters: ListOrgKeysRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise>> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling listOrgKeys().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}/api-keys`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + jsonValue.map(ModelsAPIKeyFromJSON), + ); + } + + /** + * List org-scoped API keys (no secrets) + */ + async listOrgKeys( + requestParameters: ListOrgKeysRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const response = await this.listOrgKeysRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Remove a member (owner/admin) + */ + async removeMemberRaw( + requestParameters: RemoveMemberRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling removeMember().', + ); + } + + if (requestParameters["userId"] == null) { + throw new runtime.RequiredError( + "userId", + 'Required parameter "userId" was null or undefined when calling removeMember().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}/members/{user_id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + urlPath = urlPath.replace( + `{${"user_id"}}`, + encodeURIComponent(String(requestParameters["userId"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "DELETE", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.VoidApiResponse(response); + } + + /** + * Remove a member (owner/admin) + */ + async removeMember( + requestParameters: RemoveMemberRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + await this.removeMemberRaw(requestParameters, initOverrides); + } + + /** + * Update organization (owner/admin) + */ + async updateOrgRaw( + requestParameters: UpdateOrgRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling updateOrg().', + ); + } + + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling updateOrg().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/orgs/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "PATCH", + headers: headerParameters, + query: queryParameters, + body: HandlersOrgUpdateReqToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + ModelsOrganizationFromJSON(jsonValue), + ); + } + + /** + * Update organization (owner/admin) + */ + async updateOrg( + requestParameters: UpdateOrgRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.updateOrgRaw(requestParameters, initOverrides); + return await response.value(); + } +} diff --git a/sdk/ts/src/apis/ServersApi.ts b/sdk/ts/src/apis/ServersApi.ts new file mode 100644 index 0000000..f112748 --- /dev/null +++ b/sdk/ts/src/apis/ServersApi.ts @@ -0,0 +1,435 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from "../runtime"; +import type { + DtoCreateServerRequest, + DtoServerResponse, + DtoUpdateServerRequest, +} from "../models/index"; +import { + DtoCreateServerRequestFromJSON, + DtoCreateServerRequestToJSON, + DtoServerResponseFromJSON, + DtoServerResponseToJSON, + DtoUpdateServerRequestFromJSON, + DtoUpdateServerRequestToJSON, +} from "../models/index"; + +export interface CreateServerRequest { + body: DtoCreateServerRequest; + xOrgID?: string; +} + +export interface DeleteServerRequest { + id: string; + xOrgID?: string; +} + +export interface GetServerRequest { + id: string; + xOrgID?: string; +} + +export interface ListServersRequest { + xOrgID?: string; + status?: string; + role?: string; +} + +export interface UpdateServerRequest { + id: string; + body: DtoUpdateServerRequest; + xOrgID?: string; +} + +/** + * + */ +export class ServersApi extends runtime.BaseAPI { + /** + * Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org. + * Create server (org scoped) + */ + async createServerRaw( + requestParameters: CreateServerRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling createServer().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/servers`; + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: DtoCreateServerRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoServerResponseFromJSON(jsonValue), + ); + } + + /** + * Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org. + * Create server (org scoped) + */ + async createServer( + requestParameters: CreateServerRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.createServerRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Permanently deletes the server. + * Delete server (org scoped) + */ + async deleteServerRaw( + requestParameters: DeleteServerRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling deleteServer().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/servers/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "DELETE", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + if (this.isJsonMime(response.headers.get("content-type"))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } + + /** + * Permanently deletes the server. + * Delete server (org scoped) + */ + async deleteServer( + requestParameters: DeleteServerRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.deleteServerRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Returns one server in the given organization. + * Get server by ID (org scoped) + */ + async getServerRaw( + requestParameters: GetServerRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling getServer().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/servers/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoServerResponseFromJSON(jsonValue), + ); + } + + /** + * Returns one server in the given organization. + * Get server by ID (org scoped) + */ + async getServer( + requestParameters: GetServerRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.getServerRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Returns servers for the organization in X-Org-ID. Optional filters: status, role. + * List servers (org scoped) + */ + async listServersRaw( + requestParameters: ListServersRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise>> { + const queryParameters: any = {}; + + if (requestParameters["status"] != null) { + queryParameters["status"] = requestParameters["status"]; + } + + if (requestParameters["role"] != null) { + queryParameters["role"] = requestParameters["role"]; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/servers`; + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + jsonValue.map(DtoServerResponseFromJSON), + ); + } + + /** + * Returns servers for the organization in X-Org-ID. Optional filters: status, role. + * List servers (org scoped) + */ + async listServers( + requestParameters: ListServersRequest = {}, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const response = await this.listServersRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Partially update fields; changing ssh_key_id validates ownership. + * Update server (org scoped) + */ + async updateServerRaw( + requestParameters: UpdateServerRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling updateServer().', + ); + } + + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling updateServer().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/servers/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "PATCH", + headers: headerParameters, + query: queryParameters, + body: DtoUpdateServerRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoServerResponseFromJSON(jsonValue), + ); + } + + /** + * Partially update fields; changing ssh_key_id validates ownership. + * Update server (org scoped) + */ + async updateServer( + requestParameters: UpdateServerRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.updateServerRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } +} diff --git a/sdk/ts/src/apis/SshApi.ts b/sdk/ts/src/apis/SshApi.ts new file mode 100644 index 0000000..bb1c1be --- /dev/null +++ b/sdk/ts/src/apis/SshApi.ts @@ -0,0 +1,451 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from "../runtime"; +import type { + DtoCreateSSHRequest, + DtoSshResponse, + DtoSshRevealResponse, +} from "../models/index"; +import { + DtoCreateSSHRequestFromJSON, + DtoCreateSSHRequestToJSON, + DtoSshResponseFromJSON, + DtoSshResponseToJSON, + DtoSshRevealResponseFromJSON, + DtoSshRevealResponseToJSON, +} from "../models/index"; + +export interface CreateSSHKeyRequest { + body: DtoCreateSSHRequest; + xOrgID?: string; +} + +export interface DeleteSSHKeyRequest { + id: string; + xOrgID?: string; +} + +export interface DownloadSSHKeyRequest { + xOrgID: string; + id: string; + part: DownloadSSHKeyPartEnum; +} + +export interface GetSSHKeyRequest { + id: string; + xOrgID?: string; + reveal?: boolean; +} + +export interface ListPublicSshKeysRequest { + xOrgID?: string; +} + +/** + * + */ +export class SshApi extends runtime.BaseAPI { + /** + * Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits. + * Create ssh keypair (org scoped) + */ + async createSSHKeyRaw( + requestParameters: CreateSSHKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling createSSHKey().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/ssh`; + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: DtoCreateSSHRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoSshResponseFromJSON(jsonValue), + ); + } + + /** + * Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits. + * Create ssh keypair (org scoped) + */ + async createSSHKey( + requestParameters: CreateSSHKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.createSSHKeyRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Permanently deletes a keypair. + * Delete ssh keypair (org scoped) + */ + async deleteSSHKeyRaw( + requestParameters: DeleteSSHKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling deleteSSHKey().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/ssh/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "DELETE", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + if (this.isJsonMime(response.headers.get("content-type"))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } + + /** + * Permanently deletes a keypair. + * Delete ssh keypair (org scoped) + */ + async deleteSSHKey( + requestParameters: DeleteSSHKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.deleteSSHKeyRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Download `part=public|private|both` of the keypair. `both` returns a zip file. + * Download ssh key files by ID (org scoped) + */ + async downloadSSHKeyRaw( + requestParameters: DownloadSSHKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["xOrgID"] == null) { + throw new runtime.RequiredError( + "xOrgID", + 'Required parameter "xOrgID" was null or undefined when calling downloadSSHKey().', + ); + } + + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling downloadSSHKey().', + ); + } + + if (requestParameters["part"] == null) { + throw new runtime.RequiredError( + "part", + 'Required parameter "part" was null or undefined when calling downloadSSHKey().', + ); + } + + const queryParameters: any = {}; + + if (requestParameters["part"] != null) { + queryParameters["part"] = requestParameters["part"]; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/ssh/{id}/download`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + if (this.isJsonMime(response.headers.get("content-type"))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } + + /** + * Download `part=public|private|both` of the keypair. `both` returns a zip file. + * Download ssh key files by ID (org scoped) + */ + async downloadSSHKey( + requestParameters: DownloadSSHKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.downloadSSHKeyRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Returns public key fields. Append `?reveal=true` to include the private key PEM. + * Get ssh key by ID (org scoped) + */ + async getSSHKeyRaw( + requestParameters: GetSSHKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling getSSHKey().', + ); + } + + const queryParameters: any = {}; + + if (requestParameters["reveal"] != null) { + queryParameters["reveal"] = requestParameters["reveal"]; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/ssh/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoSshRevealResponseFromJSON(jsonValue), + ); + } + + /** + * Returns public key fields. Append `?reveal=true` to include the private key PEM. + * Get ssh key by ID (org scoped) + */ + async getSSHKey( + requestParameters: GetSSHKeyRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.getSSHKeyRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Returns ssh keys for the organization in X-Org-ID. + * List ssh keys (org scoped) + */ + async listPublicSshKeysRaw( + requestParameters: ListPublicSshKeysRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/ssh`; + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + jsonValue.map(DtoSshResponseFromJSON), + ); + } + + /** + * Returns ssh keys for the organization in X-Org-ID. + * List ssh keys (org scoped) + */ + async listPublicSshKeys( + requestParameters: ListPublicSshKeysRequest = {}, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const response = await this.listPublicSshKeysRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } +} + +/** + * @export + */ +export const DownloadSSHKeyPartEnum = { + public: "public", + private: "private", + both: "both", +} as const; +export type DownloadSSHKeyPartEnum = + (typeof DownloadSSHKeyPartEnum)[keyof typeof DownloadSSHKeyPartEnum]; diff --git a/sdk/ts/src/apis/TaintsApi.ts b/sdk/ts/src/apis/TaintsApi.ts new file mode 100644 index 0000000..0179506 --- /dev/null +++ b/sdk/ts/src/apis/TaintsApi.ts @@ -0,0 +1,435 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from "../runtime"; +import type { + DtoCreateTaintRequest, + DtoTaintResponse, + DtoUpdateTaintRequest, +} from "../models/index"; +import { + DtoCreateTaintRequestFromJSON, + DtoCreateTaintRequestToJSON, + DtoTaintResponseFromJSON, + DtoTaintResponseToJSON, + DtoUpdateTaintRequestFromJSON, + DtoUpdateTaintRequestToJSON, +} from "../models/index"; + +export interface CreateTaintRequest { + body: DtoCreateTaintRequest; + xOrgID?: string; +} + +export interface DeleteTaintRequest { + id: string; + xOrgID?: string; +} + +export interface GetTaintRequest { + id: string; + xOrgID?: string; +} + +export interface ListTaintsRequest { + xOrgID?: string; + key?: string; + value?: string; + q?: string; +} + +export interface UpdateTaintRequest { + id: string; + body: DtoUpdateTaintRequest; + xOrgID?: string; +} + +/** + * + */ +export class TaintsApi extends runtime.BaseAPI { + /** + * Creates a taint. + * Create node taint (org scoped) + */ + async createTaintRaw( + requestParameters: CreateTaintRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling createTaint().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/taints`; + + const response = await this.request( + { + path: urlPath, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: DtoCreateTaintRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoTaintResponseFromJSON(jsonValue), + ); + } + + /** + * Creates a taint. + * Create node taint (org scoped) + */ + async createTaint( + requestParameters: CreateTaintRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.createTaintRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Permanently deletes the taint. + * Delete taint (org scoped) + */ + async deleteTaintRaw( + requestParameters: DeleteTaintRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling deleteTaint().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/taints/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "DELETE", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + if (this.isJsonMime(response.headers.get("content-type"))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } + + /** + * Permanently deletes the taint. + * Delete taint (org scoped) + */ + async deleteTaint( + requestParameters: DeleteTaintRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.deleteTaintRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + + /** + * Get node taint by ID (org scoped) + */ + async getTaintRaw( + requestParameters: GetTaintRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling getTaint().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/taints/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoTaintResponseFromJSON(jsonValue), + ); + } + + /** + * Get node taint by ID (org scoped) + */ + async getTaint( + requestParameters: GetTaintRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.getTaintRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Returns node taints for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools. + * List node pool taints (org scoped) + */ + async listTaintsRaw( + requestParameters: ListTaintsRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise>> { + const queryParameters: any = {}; + + if (requestParameters["key"] != null) { + queryParameters["key"] = requestParameters["key"]; + } + + if (requestParameters["value"] != null) { + queryParameters["value"] = requestParameters["value"]; + } + + if (requestParameters["q"] != null) { + queryParameters["q"] = requestParameters["q"]; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/taints`; + + const response = await this.request( + { + path: urlPath, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + jsonValue.map(DtoTaintResponseFromJSON), + ); + } + + /** + * Returns node taints for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools. + * List node pool taints (org scoped) + */ + async listTaints( + requestParameters: ListTaintsRequest = {}, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const response = await this.listTaintsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Partially update taint fields. + * Update node taint (org scoped) + */ + async updateTaintRaw( + requestParameters: UpdateTaintRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["id"] == null) { + throw new runtime.RequiredError( + "id", + 'Required parameter "id" was null or undefined when calling updateTaint().', + ); + } + + if (requestParameters["body"] == null) { + throw new runtime.RequiredError( + "body", + 'Required parameter "body" was null or undefined when calling updateTaint().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (requestParameters["xOrgID"] != null) { + headerParameters["X-Org-ID"] = String(requestParameters["xOrgID"]); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-KEY"] = + await this.configuration.apiKey("X-ORG-KEY"); // OrgKeyAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-ORG-SECRET"] = + await this.configuration.apiKey("X-ORG-SECRET"); // OrgSecretAuth authentication + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["Authorization"] = + await this.configuration.apiKey("Authorization"); // BearerAuth authentication + } + + let urlPath = `/taints/{id}`; + urlPath = urlPath.replace( + `{${"id"}}`, + encodeURIComponent(String(requestParameters["id"])), + ); + + const response = await this.request( + { + path: urlPath, + method: "PATCH", + headers: headerParameters, + query: queryParameters, + body: DtoUpdateTaintRequestToJSON(requestParameters["body"]), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + DtoTaintResponseFromJSON(jsonValue), + ); + } + + /** + * Partially update taint fields. + * Update node taint (org scoped) + */ + async updateTaint( + requestParameters: UpdateTaintRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.updateTaintRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } +} diff --git a/sdk/ts/src/apis/index.ts b/sdk/ts/src/apis/index.ts new file mode 100644 index 0000000..9f8eb0e --- /dev/null +++ b/sdk/ts/src/apis/index.ts @@ -0,0 +1,9 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from "./AuthApi"; +export * from "./MeApi"; +export * from "./MeAPIKeysApi"; +export * from "./OrgsApi"; +export * from "./ServersApi"; +export * from "./SshApi"; +export * from "./TaintsApi"; diff --git a/sdk/ts/src/index.ts b/sdk/ts/src/index.ts new file mode 100644 index 0000000..ee26377 --- /dev/null +++ b/sdk/ts/src/index.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from "./runtime"; +export * from "./apis/index"; +export * from "./models/index"; diff --git a/sdk/ts/src/models/DtoAuthStartResponse.ts b/sdk/ts/src/models/DtoAuthStartResponse.ts new file mode 100644 index 0000000..ac12114 --- /dev/null +++ b/sdk/ts/src/models/DtoAuthStartResponse.ts @@ -0,0 +1,70 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoAuthStartResponse + */ +export interface DtoAuthStartResponse { + /** + * + * @type {string} + * @memberof DtoAuthStartResponse + */ + auth_url?: string; +} + +/** + * Check if a given object implements the DtoAuthStartResponse interface. + */ +export function instanceOfDtoAuthStartResponse( + value: object, +): value is DtoAuthStartResponse { + return true; +} + +export function DtoAuthStartResponseFromJSON(json: any): DtoAuthStartResponse { + return DtoAuthStartResponseFromJSONTyped(json, false); +} + +export function DtoAuthStartResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoAuthStartResponse { + if (json == null) { + return json; + } + return { + auth_url: json["auth_url"] == null ? undefined : json["auth_url"], + }; +} + +export function DtoAuthStartResponseToJSON(json: any): DtoAuthStartResponse { + return DtoAuthStartResponseToJSONTyped(json, false); +} + +export function DtoAuthStartResponseToJSONTyped( + value?: DtoAuthStartResponse | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + auth_url: value["auth_url"], + }; +} diff --git a/sdk/ts/src/models/DtoCreateSSHRequest.ts b/sdk/ts/src/models/DtoCreateSSHRequest.ts new file mode 100644 index 0000000..c2db9ff --- /dev/null +++ b/sdk/ts/src/models/DtoCreateSSHRequest.ts @@ -0,0 +1,94 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoCreateSSHRequest + */ +export interface DtoCreateSSHRequest { + /** + * Only for RSA + * @type {number} + * @memberof DtoCreateSSHRequest + */ + bits?: number; + /** + * + * @type {string} + * @memberof DtoCreateSSHRequest + */ + comment?: string; + /** + * + * @type {string} + * @memberof DtoCreateSSHRequest + */ + name?: string; + /** + * "rsa" (default) or "ed25519" + * @type {string} + * @memberof DtoCreateSSHRequest + */ + type?: string; +} + +/** + * Check if a given object implements the DtoCreateSSHRequest interface. + */ +export function instanceOfDtoCreateSSHRequest( + value: object, +): value is DtoCreateSSHRequest { + return true; +} + +export function DtoCreateSSHRequestFromJSON(json: any): DtoCreateSSHRequest { + return DtoCreateSSHRequestFromJSONTyped(json, false); +} + +export function DtoCreateSSHRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoCreateSSHRequest { + if (json == null) { + return json; + } + return { + bits: json["bits"] == null ? undefined : json["bits"], + comment: json["comment"] == null ? undefined : json["comment"], + name: json["name"] == null ? undefined : json["name"], + type: json["type"] == null ? undefined : json["type"], + }; +} + +export function DtoCreateSSHRequestToJSON(json: any): DtoCreateSSHRequest { + return DtoCreateSSHRequestToJSONTyped(json, false); +} + +export function DtoCreateSSHRequestToJSONTyped( + value?: DtoCreateSSHRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + bits: value["bits"], + comment: value["comment"], + name: value["name"], + type: value["type"], + }; +} diff --git a/sdk/ts/src/models/DtoCreateServerRequest.ts b/sdk/ts/src/models/DtoCreateServerRequest.ts new file mode 100644 index 0000000..2dc2ea0 --- /dev/null +++ b/sdk/ts/src/models/DtoCreateServerRequest.ts @@ -0,0 +1,126 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoCreateServerRequest + */ +export interface DtoCreateServerRequest { + /** + * + * @type {string} + * @memberof DtoCreateServerRequest + */ + hostname?: string; + /** + * + * @type {string} + * @memberof DtoCreateServerRequest + */ + private_ip_address?: string; + /** + * + * @type {string} + * @memberof DtoCreateServerRequest + */ + public_ip_address?: string; + /** + * + * @type {string} + * @memberof DtoCreateServerRequest + */ + role?: string; + /** + * + * @type {string} + * @memberof DtoCreateServerRequest + */ + ssh_key_id?: string; + /** + * + * @type {string} + * @memberof DtoCreateServerRequest + */ + ssh_user?: string; + /** + * + * @type {string} + * @memberof DtoCreateServerRequest + */ + status?: string; +} + +/** + * Check if a given object implements the DtoCreateServerRequest interface. + */ +export function instanceOfDtoCreateServerRequest( + value: object, +): value is DtoCreateServerRequest { + return true; +} + +export function DtoCreateServerRequestFromJSON( + json: any, +): DtoCreateServerRequest { + return DtoCreateServerRequestFromJSONTyped(json, false); +} + +export function DtoCreateServerRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoCreateServerRequest { + if (json == null) { + return json; + } + return { + hostname: json["hostname"] == null ? undefined : json["hostname"], + private_ip_address: + json["private_ip_address"] == null + ? undefined + : json["private_ip_address"], + public_ip_address: + json["public_ip_address"] == null ? undefined : json["public_ip_address"], + role: json["role"] == null ? undefined : json["role"], + ssh_key_id: json["ssh_key_id"] == null ? undefined : json["ssh_key_id"], + ssh_user: json["ssh_user"] == null ? undefined : json["ssh_user"], + status: json["status"] == null ? undefined : json["status"], + }; +} + +export function DtoCreateServerRequestToJSON( + json: any, +): DtoCreateServerRequest { + return DtoCreateServerRequestToJSONTyped(json, false); +} + +export function DtoCreateServerRequestToJSONTyped( + value?: DtoCreateServerRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + hostname: value["hostname"], + private_ip_address: value["private_ip_address"], + public_ip_address: value["public_ip_address"], + role: value["role"], + ssh_key_id: value["ssh_key_id"], + ssh_user: value["ssh_user"], + status: value["status"], + }; +} diff --git a/sdk/ts/src/models/DtoCreateTaintRequest.ts b/sdk/ts/src/models/DtoCreateTaintRequest.ts new file mode 100644 index 0000000..01357eb --- /dev/null +++ b/sdk/ts/src/models/DtoCreateTaintRequest.ts @@ -0,0 +1,88 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoCreateTaintRequest + */ +export interface DtoCreateTaintRequest { + /** + * + * @type {string} + * @memberof DtoCreateTaintRequest + */ + effect?: string; + /** + * + * @type {string} + * @memberof DtoCreateTaintRequest + */ + key?: string; + /** + * + * @type {string} + * @memberof DtoCreateTaintRequest + */ + value?: string; +} + +/** + * Check if a given object implements the DtoCreateTaintRequest interface. + */ +export function instanceOfDtoCreateTaintRequest( + value: object, +): value is DtoCreateTaintRequest { + return true; +} + +export function DtoCreateTaintRequestFromJSON( + json: any, +): DtoCreateTaintRequest { + return DtoCreateTaintRequestFromJSONTyped(json, false); +} + +export function DtoCreateTaintRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoCreateTaintRequest { + if (json == null) { + return json; + } + return { + effect: json["effect"] == null ? undefined : json["effect"], + key: json["key"] == null ? undefined : json["key"], + value: json["value"] == null ? undefined : json["value"], + }; +} + +export function DtoCreateTaintRequestToJSON(json: any): DtoCreateTaintRequest { + return DtoCreateTaintRequestToJSONTyped(json, false); +} + +export function DtoCreateTaintRequestToJSONTyped( + value?: DtoCreateTaintRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + effect: value["effect"], + key: value["key"], + value: value["value"], + }; +} diff --git a/sdk/ts/src/models/DtoJWK.ts b/sdk/ts/src/models/DtoJWK.ts new file mode 100644 index 0000000..a9262eb --- /dev/null +++ b/sdk/ts/src/models/DtoJWK.ts @@ -0,0 +1,116 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoJWK + */ +export interface DtoJWK { + /** + * + * @type {string} + * @memberof DtoJWK + */ + alg?: string; + /** + * + * @type {string} + * @memberof DtoJWK + */ + e?: string; + /** + * + * @type {string} + * @memberof DtoJWK + */ + kid?: string; + /** + * + * @type {string} + * @memberof DtoJWK + */ + kty?: string; + /** + * + * @type {string} + * @memberof DtoJWK + */ + n?: string; + /** + * + * @type {string} + * @memberof DtoJWK + */ + use?: string; + /** + * + * @type {string} + * @memberof DtoJWK + */ + x?: string; +} + +/** + * Check if a given object implements the DtoJWK interface. + */ +export function instanceOfDtoJWK(value: object): value is DtoJWK { + return true; +} + +export function DtoJWKFromJSON(json: any): DtoJWK { + return DtoJWKFromJSONTyped(json, false); +} + +export function DtoJWKFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoJWK { + if (json == null) { + return json; + } + return { + alg: json["alg"] == null ? undefined : json["alg"], + e: json["e"] == null ? undefined : json["e"], + kid: json["kid"] == null ? undefined : json["kid"], + kty: json["kty"] == null ? undefined : json["kty"], + n: json["n"] == null ? undefined : json["n"], + use: json["use"] == null ? undefined : json["use"], + x: json["x"] == null ? undefined : json["x"], + }; +} + +export function DtoJWKToJSON(json: any): DtoJWK { + return DtoJWKToJSONTyped(json, false); +} + +export function DtoJWKToJSONTyped( + value?: DtoJWK | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + alg: value["alg"], + e: value["e"], + kid: value["kid"], + kty: value["kty"], + n: value["n"], + use: value["use"], + x: value["x"], + }; +} diff --git a/sdk/ts/src/models/DtoJWKS.ts b/sdk/ts/src/models/DtoJWKS.ts new file mode 100644 index 0000000..c227206 --- /dev/null +++ b/sdk/ts/src/models/DtoJWKS.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +import type { DtoJWK } from "./DtoJWK"; +import { + DtoJWKFromJSON, + DtoJWKFromJSONTyped, + DtoJWKToJSON, + DtoJWKToJSONTyped, +} from "./DtoJWK"; + +/** + * + * @export + * @interface DtoJWKS + */ +export interface DtoJWKS { + /** + * + * @type {Array} + * @memberof DtoJWKS + */ + keys?: Array; +} + +/** + * Check if a given object implements the DtoJWKS interface. + */ +export function instanceOfDtoJWKS(value: object): value is DtoJWKS { + return true; +} + +export function DtoJWKSFromJSON(json: any): DtoJWKS { + return DtoJWKSFromJSONTyped(json, false); +} + +export function DtoJWKSFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoJWKS { + if (json == null) { + return json; + } + return { + keys: + json["keys"] == null + ? undefined + : (json["keys"] as Array).map(DtoJWKFromJSON), + }; +} + +export function DtoJWKSToJSON(json: any): DtoJWKS { + return DtoJWKSToJSONTyped(json, false); +} + +export function DtoJWKSToJSONTyped( + value?: DtoJWKS | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + keys: + value["keys"] == null + ? undefined + : (value["keys"] as Array).map(DtoJWKToJSON), + }; +} diff --git a/sdk/ts/src/models/DtoLogoutRequest.ts b/sdk/ts/src/models/DtoLogoutRequest.ts new file mode 100644 index 0000000..054e38d --- /dev/null +++ b/sdk/ts/src/models/DtoLogoutRequest.ts @@ -0,0 +1,71 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoLogoutRequest + */ +export interface DtoLogoutRequest { + /** + * + * @type {string} + * @memberof DtoLogoutRequest + */ + refresh_token?: string; +} + +/** + * Check if a given object implements the DtoLogoutRequest interface. + */ +export function instanceOfDtoLogoutRequest( + value: object, +): value is DtoLogoutRequest { + return true; +} + +export function DtoLogoutRequestFromJSON(json: any): DtoLogoutRequest { + return DtoLogoutRequestFromJSONTyped(json, false); +} + +export function DtoLogoutRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoLogoutRequest { + if (json == null) { + return json; + } + return { + refresh_token: + json["refresh_token"] == null ? undefined : json["refresh_token"], + }; +} + +export function DtoLogoutRequestToJSON(json: any): DtoLogoutRequest { + return DtoLogoutRequestToJSONTyped(json, false); +} + +export function DtoLogoutRequestToJSONTyped( + value?: DtoLogoutRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + refresh_token: value["refresh_token"], + }; +} diff --git a/sdk/ts/src/models/DtoRefreshRequest.ts b/sdk/ts/src/models/DtoRefreshRequest.ts new file mode 100644 index 0000000..4cf2061 --- /dev/null +++ b/sdk/ts/src/models/DtoRefreshRequest.ts @@ -0,0 +1,71 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoRefreshRequest + */ +export interface DtoRefreshRequest { + /** + * + * @type {string} + * @memberof DtoRefreshRequest + */ + refresh_token?: string; +} + +/** + * Check if a given object implements the DtoRefreshRequest interface. + */ +export function instanceOfDtoRefreshRequest( + value: object, +): value is DtoRefreshRequest { + return true; +} + +export function DtoRefreshRequestFromJSON(json: any): DtoRefreshRequest { + return DtoRefreshRequestFromJSONTyped(json, false); +} + +export function DtoRefreshRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoRefreshRequest { + if (json == null) { + return json; + } + return { + refresh_token: + json["refresh_token"] == null ? undefined : json["refresh_token"], + }; +} + +export function DtoRefreshRequestToJSON(json: any): DtoRefreshRequest { + return DtoRefreshRequestToJSONTyped(json, false); +} + +export function DtoRefreshRequestToJSONTyped( + value?: DtoRefreshRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + refresh_token: value["refresh_token"], + }; +} diff --git a/sdk/ts/src/models/DtoServerResponse.ts b/sdk/ts/src/models/DtoServerResponse.ts new file mode 100644 index 0000000..3e94c67 --- /dev/null +++ b/sdk/ts/src/models/DtoServerResponse.ts @@ -0,0 +1,155 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoServerResponse + */ +export interface DtoServerResponse { + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + created_at?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + hostname?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + id?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + organization_id?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + private_ip_address?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + public_ip_address?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + role?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + ssh_key_id?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + ssh_user?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + status?: string; + /** + * + * @type {string} + * @memberof DtoServerResponse + */ + updated_at?: string; +} + +/** + * Check if a given object implements the DtoServerResponse interface. + */ +export function instanceOfDtoServerResponse( + value: object, +): value is DtoServerResponse { + return true; +} + +export function DtoServerResponseFromJSON(json: any): DtoServerResponse { + return DtoServerResponseFromJSONTyped(json, false); +} + +export function DtoServerResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoServerResponse { + if (json == null) { + return json; + } + return { + created_at: json["created_at"] == null ? undefined : json["created_at"], + hostname: json["hostname"] == null ? undefined : json["hostname"], + id: json["id"] == null ? undefined : json["id"], + organization_id: + json["organization_id"] == null ? undefined : json["organization_id"], + private_ip_address: + json["private_ip_address"] == null + ? undefined + : json["private_ip_address"], + public_ip_address: + json["public_ip_address"] == null ? undefined : json["public_ip_address"], + role: json["role"] == null ? undefined : json["role"], + ssh_key_id: json["ssh_key_id"] == null ? undefined : json["ssh_key_id"], + ssh_user: json["ssh_user"] == null ? undefined : json["ssh_user"], + status: json["status"] == null ? undefined : json["status"], + updated_at: json["updated_at"] == null ? undefined : json["updated_at"], + }; +} + +export function DtoServerResponseToJSON(json: any): DtoServerResponse { + return DtoServerResponseToJSONTyped(json, false); +} + +export function DtoServerResponseToJSONTyped( + value?: DtoServerResponse | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + created_at: value["created_at"], + hostname: value["hostname"], + id: value["id"], + organization_id: value["organization_id"], + private_ip_address: value["private_ip_address"], + public_ip_address: value["public_ip_address"], + role: value["role"], + ssh_key_id: value["ssh_key_id"], + ssh_user: value["ssh_user"], + status: value["status"], + updated_at: value["updated_at"], + }; +} diff --git a/sdk/ts/src/models/DtoSshResponse.ts b/sdk/ts/src/models/DtoSshResponse.ts new file mode 100644 index 0000000..4e1aed0 --- /dev/null +++ b/sdk/ts/src/models/DtoSshResponse.ts @@ -0,0 +1,119 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoSshResponse + */ +export interface DtoSshResponse { + /** + * + * @type {string} + * @memberof DtoSshResponse + */ + created_at?: string; + /** + * + * @type {string} + * @memberof DtoSshResponse + */ + fingerprint?: string; + /** + * + * @type {string} + * @memberof DtoSshResponse + */ + id?: string; + /** + * + * @type {string} + * @memberof DtoSshResponse + */ + name?: string; + /** + * + * @type {string} + * @memberof DtoSshResponse + */ + organization_id?: string; + /** + * + * @type {string} + * @memberof DtoSshResponse + */ + public_key?: string; + /** + * + * @type {string} + * @memberof DtoSshResponse + */ + updated_at?: string; +} + +/** + * Check if a given object implements the DtoSshResponse interface. + */ +export function instanceOfDtoSshResponse( + value: object, +): value is DtoSshResponse { + return true; +} + +export function DtoSshResponseFromJSON(json: any): DtoSshResponse { + return DtoSshResponseFromJSONTyped(json, false); +} + +export function DtoSshResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoSshResponse { + if (json == null) { + return json; + } + return { + created_at: json["created_at"] == null ? undefined : json["created_at"], + fingerprint: json["fingerprint"] == null ? undefined : json["fingerprint"], + id: json["id"] == null ? undefined : json["id"], + name: json["name"] == null ? undefined : json["name"], + organization_id: + json["organization_id"] == null ? undefined : json["organization_id"], + public_key: json["public_key"] == null ? undefined : json["public_key"], + updated_at: json["updated_at"] == null ? undefined : json["updated_at"], + }; +} + +export function DtoSshResponseToJSON(json: any): DtoSshResponse { + return DtoSshResponseToJSONTyped(json, false); +} + +export function DtoSshResponseToJSONTyped( + value?: DtoSshResponse | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + created_at: value["created_at"], + fingerprint: value["fingerprint"], + id: value["id"], + name: value["name"], + organization_id: value["organization_id"], + public_key: value["public_key"], + updated_at: value["updated_at"], + }; +} diff --git a/sdk/ts/src/models/DtoSshRevealResponse.ts b/sdk/ts/src/models/DtoSshRevealResponse.ts new file mode 100644 index 0000000..eb60798 --- /dev/null +++ b/sdk/ts/src/models/DtoSshRevealResponse.ts @@ -0,0 +1,127 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoSshRevealResponse + */ +export interface DtoSshRevealResponse { + /** + * + * @type {string} + * @memberof DtoSshRevealResponse + */ + created_at?: string; + /** + * + * @type {string} + * @memberof DtoSshRevealResponse + */ + fingerprint?: string; + /** + * + * @type {string} + * @memberof DtoSshRevealResponse + */ + id?: string; + /** + * + * @type {string} + * @memberof DtoSshRevealResponse + */ + name?: string; + /** + * + * @type {string} + * @memberof DtoSshRevealResponse + */ + organization_id?: string; + /** + * + * @type {string} + * @memberof DtoSshRevealResponse + */ + private_key?: string; + /** + * + * @type {string} + * @memberof DtoSshRevealResponse + */ + public_key?: string; + /** + * + * @type {string} + * @memberof DtoSshRevealResponse + */ + updated_at?: string; +} + +/** + * Check if a given object implements the DtoSshRevealResponse interface. + */ +export function instanceOfDtoSshRevealResponse( + value: object, +): value is DtoSshRevealResponse { + return true; +} + +export function DtoSshRevealResponseFromJSON(json: any): DtoSshRevealResponse { + return DtoSshRevealResponseFromJSONTyped(json, false); +} + +export function DtoSshRevealResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoSshRevealResponse { + if (json == null) { + return json; + } + return { + created_at: json["created_at"] == null ? undefined : json["created_at"], + fingerprint: json["fingerprint"] == null ? undefined : json["fingerprint"], + id: json["id"] == null ? undefined : json["id"], + name: json["name"] == null ? undefined : json["name"], + organization_id: + json["organization_id"] == null ? undefined : json["organization_id"], + private_key: json["private_key"] == null ? undefined : json["private_key"], + public_key: json["public_key"] == null ? undefined : json["public_key"], + updated_at: json["updated_at"] == null ? undefined : json["updated_at"], + }; +} + +export function DtoSshRevealResponseToJSON(json: any): DtoSshRevealResponse { + return DtoSshRevealResponseToJSONTyped(json, false); +} + +export function DtoSshRevealResponseToJSONTyped( + value?: DtoSshRevealResponse | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + created_at: value["created_at"], + fingerprint: value["fingerprint"], + id: value["id"], + name: value["name"], + organization_id: value["organization_id"], + private_key: value["private_key"], + public_key: value["public_key"], + updated_at: value["updated_at"], + }; +} diff --git a/sdk/ts/src/models/DtoTaintResponse.ts b/sdk/ts/src/models/DtoTaintResponse.ts new file mode 100644 index 0000000..f7c59e6 --- /dev/null +++ b/sdk/ts/src/models/DtoTaintResponse.ts @@ -0,0 +1,94 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoTaintResponse + */ +export interface DtoTaintResponse { + /** + * + * @type {string} + * @memberof DtoTaintResponse + */ + effect?: string; + /** + * + * @type {string} + * @memberof DtoTaintResponse + */ + id?: string; + /** + * + * @type {string} + * @memberof DtoTaintResponse + */ + key?: string; + /** + * + * @type {string} + * @memberof DtoTaintResponse + */ + value?: string; +} + +/** + * Check if a given object implements the DtoTaintResponse interface. + */ +export function instanceOfDtoTaintResponse( + value: object, +): value is DtoTaintResponse { + return true; +} + +export function DtoTaintResponseFromJSON(json: any): DtoTaintResponse { + return DtoTaintResponseFromJSONTyped(json, false); +} + +export function DtoTaintResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoTaintResponse { + if (json == null) { + return json; + } + return { + effect: json["effect"] == null ? undefined : json["effect"], + id: json["id"] == null ? undefined : json["id"], + key: json["key"] == null ? undefined : json["key"], + value: json["value"] == null ? undefined : json["value"], + }; +} + +export function DtoTaintResponseToJSON(json: any): DtoTaintResponse { + return DtoTaintResponseToJSONTyped(json, false); +} + +export function DtoTaintResponseToJSONTyped( + value?: DtoTaintResponse | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + effect: value["effect"], + id: value["id"], + key: value["key"], + value: value["value"], + }; +} diff --git a/sdk/ts/src/models/DtoTokenPair.ts b/sdk/ts/src/models/DtoTokenPair.ts new file mode 100644 index 0000000..54be880 --- /dev/null +++ b/sdk/ts/src/models/DtoTokenPair.ts @@ -0,0 +1,94 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoTokenPair + */ +export interface DtoTokenPair { + /** + * + * @type {string} + * @memberof DtoTokenPair + */ + access_token?: string; + /** + * + * @type {number} + * @memberof DtoTokenPair + */ + expires_in?: number; + /** + * + * @type {string} + * @memberof DtoTokenPair + */ + refresh_token?: string; + /** + * + * @type {string} + * @memberof DtoTokenPair + */ + token_type?: string; +} + +/** + * Check if a given object implements the DtoTokenPair interface. + */ +export function instanceOfDtoTokenPair(value: object): value is DtoTokenPair { + return true; +} + +export function DtoTokenPairFromJSON(json: any): DtoTokenPair { + return DtoTokenPairFromJSONTyped(json, false); +} + +export function DtoTokenPairFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoTokenPair { + if (json == null) { + return json; + } + return { + access_token: + json["access_token"] == null ? undefined : json["access_token"], + expires_in: json["expires_in"] == null ? undefined : json["expires_in"], + refresh_token: + json["refresh_token"] == null ? undefined : json["refresh_token"], + token_type: json["token_type"] == null ? undefined : json["token_type"], + }; +} + +export function DtoTokenPairToJSON(json: any): DtoTokenPair { + return DtoTokenPairToJSONTyped(json, false); +} + +export function DtoTokenPairToJSONTyped( + value?: DtoTokenPair | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + access_token: value["access_token"], + expires_in: value["expires_in"], + refresh_token: value["refresh_token"], + token_type: value["token_type"], + }; +} diff --git a/sdk/ts/src/models/DtoUpdateServerRequest.ts b/sdk/ts/src/models/DtoUpdateServerRequest.ts new file mode 100644 index 0000000..edbde25 --- /dev/null +++ b/sdk/ts/src/models/DtoUpdateServerRequest.ts @@ -0,0 +1,126 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoUpdateServerRequest + */ +export interface DtoUpdateServerRequest { + /** + * + * @type {string} + * @memberof DtoUpdateServerRequest + */ + hostname?: string; + /** + * + * @type {string} + * @memberof DtoUpdateServerRequest + */ + private_ip_address?: string; + /** + * + * @type {string} + * @memberof DtoUpdateServerRequest + */ + public_ip_address?: string; + /** + * + * @type {string} + * @memberof DtoUpdateServerRequest + */ + role?: string; + /** + * + * @type {string} + * @memberof DtoUpdateServerRequest + */ + ssh_key_id?: string; + /** + * + * @type {string} + * @memberof DtoUpdateServerRequest + */ + ssh_user?: string; + /** + * + * @type {string} + * @memberof DtoUpdateServerRequest + */ + status?: string; +} + +/** + * Check if a given object implements the DtoUpdateServerRequest interface. + */ +export function instanceOfDtoUpdateServerRequest( + value: object, +): value is DtoUpdateServerRequest { + return true; +} + +export function DtoUpdateServerRequestFromJSON( + json: any, +): DtoUpdateServerRequest { + return DtoUpdateServerRequestFromJSONTyped(json, false); +} + +export function DtoUpdateServerRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoUpdateServerRequest { + if (json == null) { + return json; + } + return { + hostname: json["hostname"] == null ? undefined : json["hostname"], + private_ip_address: + json["private_ip_address"] == null + ? undefined + : json["private_ip_address"], + public_ip_address: + json["public_ip_address"] == null ? undefined : json["public_ip_address"], + role: json["role"] == null ? undefined : json["role"], + ssh_key_id: json["ssh_key_id"] == null ? undefined : json["ssh_key_id"], + ssh_user: json["ssh_user"] == null ? undefined : json["ssh_user"], + status: json["status"] == null ? undefined : json["status"], + }; +} + +export function DtoUpdateServerRequestToJSON( + json: any, +): DtoUpdateServerRequest { + return DtoUpdateServerRequestToJSONTyped(json, false); +} + +export function DtoUpdateServerRequestToJSONTyped( + value?: DtoUpdateServerRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + hostname: value["hostname"], + private_ip_address: value["private_ip_address"], + public_ip_address: value["public_ip_address"], + role: value["role"], + ssh_key_id: value["ssh_key_id"], + ssh_user: value["ssh_user"], + status: value["status"], + }; +} diff --git a/sdk/ts/src/models/DtoUpdateTaintRequest.ts b/sdk/ts/src/models/DtoUpdateTaintRequest.ts new file mode 100644 index 0000000..bc3c0bf --- /dev/null +++ b/sdk/ts/src/models/DtoUpdateTaintRequest.ts @@ -0,0 +1,88 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface DtoUpdateTaintRequest + */ +export interface DtoUpdateTaintRequest { + /** + * + * @type {string} + * @memberof DtoUpdateTaintRequest + */ + effect?: string; + /** + * + * @type {string} + * @memberof DtoUpdateTaintRequest + */ + key?: string; + /** + * + * @type {string} + * @memberof DtoUpdateTaintRequest + */ + value?: string; +} + +/** + * Check if a given object implements the DtoUpdateTaintRequest interface. + */ +export function instanceOfDtoUpdateTaintRequest( + value: object, +): value is DtoUpdateTaintRequest { + return true; +} + +export function DtoUpdateTaintRequestFromJSON( + json: any, +): DtoUpdateTaintRequest { + return DtoUpdateTaintRequestFromJSONTyped(json, false); +} + +export function DtoUpdateTaintRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): DtoUpdateTaintRequest { + if (json == null) { + return json; + } + return { + effect: json["effect"] == null ? undefined : json["effect"], + key: json["key"] == null ? undefined : json["key"], + value: json["value"] == null ? undefined : json["value"], + }; +} + +export function DtoUpdateTaintRequestToJSON(json: any): DtoUpdateTaintRequest { + return DtoUpdateTaintRequestToJSONTyped(json, false); +} + +export function DtoUpdateTaintRequestToJSONTyped( + value?: DtoUpdateTaintRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + effect: value["effect"], + key: value["key"], + value: value["value"], + }; +} diff --git a/sdk/ts/src/models/HandlersCreateUserKeyRequest.ts b/sdk/ts/src/models/HandlersCreateUserKeyRequest.ts new file mode 100644 index 0000000..5d4ed26 --- /dev/null +++ b/sdk/ts/src/models/HandlersCreateUserKeyRequest.ts @@ -0,0 +1,83 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersCreateUserKeyRequest + */ +export interface HandlersCreateUserKeyRequest { + /** + * optional TTL + * @type {number} + * @memberof HandlersCreateUserKeyRequest + */ + expires_in_hours?: number; + /** + * + * @type {string} + * @memberof HandlersCreateUserKeyRequest + */ + name?: string; +} + +/** + * Check if a given object implements the HandlersCreateUserKeyRequest interface. + */ +export function instanceOfHandlersCreateUserKeyRequest( + value: object, +): value is HandlersCreateUserKeyRequest { + return true; +} + +export function HandlersCreateUserKeyRequestFromJSON( + json: any, +): HandlersCreateUserKeyRequest { + return HandlersCreateUserKeyRequestFromJSONTyped(json, false); +} + +export function HandlersCreateUserKeyRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersCreateUserKeyRequest { + if (json == null) { + return json; + } + return { + expires_in_hours: + json["expires_in_hours"] == null ? undefined : json["expires_in_hours"], + name: json["name"] == null ? undefined : json["name"], + }; +} + +export function HandlersCreateUserKeyRequestToJSON( + json: any, +): HandlersCreateUserKeyRequest { + return HandlersCreateUserKeyRequestToJSONTyped(json, false); +} + +export function HandlersCreateUserKeyRequestToJSONTyped( + value?: HandlersCreateUserKeyRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + expires_in_hours: value["expires_in_hours"], + name: value["name"], + }; +} diff --git a/sdk/ts/src/models/HandlersMeResponse.ts b/sdk/ts/src/models/HandlersMeResponse.ts new file mode 100644 index 0000000..c97cb08 --- /dev/null +++ b/sdk/ts/src/models/HandlersMeResponse.ts @@ -0,0 +1,171 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +import type { ModelsUserEmail } from "./ModelsUserEmail"; +import { + ModelsUserEmailFromJSON, + ModelsUserEmailFromJSONTyped, + ModelsUserEmailToJSON, + ModelsUserEmailToJSONTyped, +} from "./ModelsUserEmail"; +import type { ModelsOrganization } from "./ModelsOrganization"; +import { + ModelsOrganizationFromJSON, + ModelsOrganizationFromJSONTyped, + ModelsOrganizationToJSON, + ModelsOrganizationToJSONTyped, +} from "./ModelsOrganization"; + +/** + * + * @export + * @interface HandlersMeResponse + */ +export interface HandlersMeResponse { + /** + * + * @type {string} + * @memberof HandlersMeResponse + */ + avatar_url?: string; + /** + * + * @type {Date} + * @memberof HandlersMeResponse + */ + created_at?: Date; + /** + * + * @type {string} + * @memberof HandlersMeResponse + */ + display_name?: string; + /** + * + * @type {Array} + * @memberof HandlersMeResponse + */ + emails?: Array; + /** + * example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + * @type {string} + * @memberof HandlersMeResponse + */ + id?: string; + /** + * + * @type {boolean} + * @memberof HandlersMeResponse + */ + is_disabled?: boolean; + /** + * + * @type {Array} + * @memberof HandlersMeResponse + */ + organizations?: Array; + /** + * + * @type {string} + * @memberof HandlersMeResponse + */ + primary_email?: string; + /** + * + * @type {Date} + * @memberof HandlersMeResponse + */ + updated_at?: Date; +} + +/** + * Check if a given object implements the HandlersMeResponse interface. + */ +export function instanceOfHandlersMeResponse( + value: object, +): value is HandlersMeResponse { + return true; +} + +export function HandlersMeResponseFromJSON(json: any): HandlersMeResponse { + return HandlersMeResponseFromJSONTyped(json, false); +} + +export function HandlersMeResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersMeResponse { + if (json == null) { + return json; + } + return { + avatar_url: json["avatar_url"] == null ? undefined : json["avatar_url"], + created_at: + json["created_at"] == null ? undefined : new Date(json["created_at"]), + display_name: + json["display_name"] == null ? undefined : json["display_name"], + emails: + json["emails"] == null + ? undefined + : (json["emails"] as Array).map(ModelsUserEmailFromJSON), + id: json["id"] == null ? undefined : json["id"], + is_disabled: json["is_disabled"] == null ? undefined : json["is_disabled"], + organizations: + json["organizations"] == null + ? undefined + : (json["organizations"] as Array).map(ModelsOrganizationFromJSON), + primary_email: + json["primary_email"] == null ? undefined : json["primary_email"], + updated_at: + json["updated_at"] == null ? undefined : new Date(json["updated_at"]), + }; +} + +export function HandlersMeResponseToJSON(json: any): HandlersMeResponse { + return HandlersMeResponseToJSONTyped(json, false); +} + +export function HandlersMeResponseToJSONTyped( + value?: HandlersMeResponse | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + avatar_url: value["avatar_url"], + created_at: + value["created_at"] == null + ? value["created_at"] + : value["created_at"].toISOString(), + display_name: value["display_name"], + emails: + value["emails"] == null + ? undefined + : (value["emails"] as Array).map(ModelsUserEmailToJSON), + id: value["id"], + is_disabled: value["is_disabled"], + organizations: + value["organizations"] == null + ? undefined + : (value["organizations"] as Array).map(ModelsOrganizationToJSON), + primary_email: value["primary_email"], + updated_at: + value["updated_at"] == null + ? value["updated_at"] + : value["updated_at"].toISOString(), + }; +} diff --git a/sdk/ts/src/models/HandlersMemberOut.ts b/sdk/ts/src/models/HandlersMemberOut.ts new file mode 100644 index 0000000..4dde0ab --- /dev/null +++ b/sdk/ts/src/models/HandlersMemberOut.ts @@ -0,0 +1,86 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersMemberOut + */ +export interface HandlersMemberOut { + /** + * + * @type {string} + * @memberof HandlersMemberOut + */ + email?: string; + /** + * owner/admin/member + * @type {string} + * @memberof HandlersMemberOut + */ + role?: string; + /** + * + * @type {string} + * @memberof HandlersMemberOut + */ + user_id?: string; +} + +/** + * Check if a given object implements the HandlersMemberOut interface. + */ +export function instanceOfHandlersMemberOut( + value: object, +): value is HandlersMemberOut { + return true; +} + +export function HandlersMemberOutFromJSON(json: any): HandlersMemberOut { + return HandlersMemberOutFromJSONTyped(json, false); +} + +export function HandlersMemberOutFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersMemberOut { + if (json == null) { + return json; + } + return { + email: json["email"] == null ? undefined : json["email"], + role: json["role"] == null ? undefined : json["role"], + user_id: json["user_id"] == null ? undefined : json["user_id"], + }; +} + +export function HandlersMemberOutToJSON(json: any): HandlersMemberOut { + return HandlersMemberOutToJSONTyped(json, false); +} + +export function HandlersMemberOutToJSONTyped( + value?: HandlersMemberOut | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + email: value["email"], + role: value["role"], + user_id: value["user_id"], + }; +} diff --git a/sdk/ts/src/models/HandlersMemberUpsertReq.ts b/sdk/ts/src/models/HandlersMemberUpsertReq.ts new file mode 100644 index 0000000..6fb27b6 --- /dev/null +++ b/sdk/ts/src/models/HandlersMemberUpsertReq.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersMemberUpsertReq + */ +export interface HandlersMemberUpsertReq { + /** + * + * @type {string} + * @memberof HandlersMemberUpsertReq + */ + role?: string; + /** + * + * @type {string} + * @memberof HandlersMemberUpsertReq + */ + user_id?: string; +} + +/** + * Check if a given object implements the HandlersMemberUpsertReq interface. + */ +export function instanceOfHandlersMemberUpsertReq( + value: object, +): value is HandlersMemberUpsertReq { + return true; +} + +export function HandlersMemberUpsertReqFromJSON( + json: any, +): HandlersMemberUpsertReq { + return HandlersMemberUpsertReqFromJSONTyped(json, false); +} + +export function HandlersMemberUpsertReqFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersMemberUpsertReq { + if (json == null) { + return json; + } + return { + role: json["role"] == null ? undefined : json["role"], + user_id: json["user_id"] == null ? undefined : json["user_id"], + }; +} + +export function HandlersMemberUpsertReqToJSON( + json: any, +): HandlersMemberUpsertReq { + return HandlersMemberUpsertReqToJSONTyped(json, false); +} + +export function HandlersMemberUpsertReqToJSONTyped( + value?: HandlersMemberUpsertReq | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + role: value["role"], + user_id: value["user_id"], + }; +} diff --git a/sdk/ts/src/models/HandlersOrgCreateReq.ts b/sdk/ts/src/models/HandlersOrgCreateReq.ts new file mode 100644 index 0000000..8b82e36 --- /dev/null +++ b/sdk/ts/src/models/HandlersOrgCreateReq.ts @@ -0,0 +1,78 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersOrgCreateReq + */ +export interface HandlersOrgCreateReq { + /** + * + * @type {string} + * @memberof HandlersOrgCreateReq + */ + domain?: string; + /** + * + * @type {string} + * @memberof HandlersOrgCreateReq + */ + name?: string; +} + +/** + * Check if a given object implements the HandlersOrgCreateReq interface. + */ +export function instanceOfHandlersOrgCreateReq( + value: object, +): value is HandlersOrgCreateReq { + return true; +} + +export function HandlersOrgCreateReqFromJSON(json: any): HandlersOrgCreateReq { + return HandlersOrgCreateReqFromJSONTyped(json, false); +} + +export function HandlersOrgCreateReqFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersOrgCreateReq { + if (json == null) { + return json; + } + return { + domain: json["domain"] == null ? undefined : json["domain"], + name: json["name"] == null ? undefined : json["name"], + }; +} + +export function HandlersOrgCreateReqToJSON(json: any): HandlersOrgCreateReq { + return HandlersOrgCreateReqToJSONTyped(json, false); +} + +export function HandlersOrgCreateReqToJSONTyped( + value?: HandlersOrgCreateReq | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + domain: value["domain"], + name: value["name"], + }; +} diff --git a/sdk/ts/src/models/HandlersOrgKeyCreateReq.ts b/sdk/ts/src/models/HandlersOrgKeyCreateReq.ts new file mode 100644 index 0000000..823ad90 --- /dev/null +++ b/sdk/ts/src/models/HandlersOrgKeyCreateReq.ts @@ -0,0 +1,83 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersOrgKeyCreateReq + */ +export interface HandlersOrgKeyCreateReq { + /** + * + * @type {number} + * @memberof HandlersOrgKeyCreateReq + */ + expires_in_hours?: number; + /** + * + * @type {string} + * @memberof HandlersOrgKeyCreateReq + */ + name?: string; +} + +/** + * Check if a given object implements the HandlersOrgKeyCreateReq interface. + */ +export function instanceOfHandlersOrgKeyCreateReq( + value: object, +): value is HandlersOrgKeyCreateReq { + return true; +} + +export function HandlersOrgKeyCreateReqFromJSON( + json: any, +): HandlersOrgKeyCreateReq { + return HandlersOrgKeyCreateReqFromJSONTyped(json, false); +} + +export function HandlersOrgKeyCreateReqFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersOrgKeyCreateReq { + if (json == null) { + return json; + } + return { + expires_in_hours: + json["expires_in_hours"] == null ? undefined : json["expires_in_hours"], + name: json["name"] == null ? undefined : json["name"], + }; +} + +export function HandlersOrgKeyCreateReqToJSON( + json: any, +): HandlersOrgKeyCreateReq { + return HandlersOrgKeyCreateReqToJSONTyped(json, false); +} + +export function HandlersOrgKeyCreateReqToJSONTyped( + value?: HandlersOrgKeyCreateReq | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + expires_in_hours: value["expires_in_hours"], + name: value["name"], + }; +} diff --git a/sdk/ts/src/models/HandlersOrgKeyCreateResp.ts b/sdk/ts/src/models/HandlersOrgKeyCreateResp.ts new file mode 100644 index 0000000..45cf555 --- /dev/null +++ b/sdk/ts/src/models/HandlersOrgKeyCreateResp.ts @@ -0,0 +1,122 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersOrgKeyCreateResp + */ +export interface HandlersOrgKeyCreateResp { + /** + * + * @type {string} + * @memberof HandlersOrgKeyCreateResp + */ + created_at?: string; + /** + * + * @type {string} + * @memberof HandlersOrgKeyCreateResp + */ + expires_at?: string; + /** + * + * @type {string} + * @memberof HandlersOrgKeyCreateResp + */ + id?: string; + /** + * + * @type {string} + * @memberof HandlersOrgKeyCreateResp + */ + name?: string; + /** + * shown once: + * @type {string} + * @memberof HandlersOrgKeyCreateResp + */ + org_key?: string; + /** + * shown once: + * @type {string} + * @memberof HandlersOrgKeyCreateResp + */ + org_secret?: string; + /** + * "org" + * @type {string} + * @memberof HandlersOrgKeyCreateResp + */ + scope?: string; +} + +/** + * Check if a given object implements the HandlersOrgKeyCreateResp interface. + */ +export function instanceOfHandlersOrgKeyCreateResp( + value: object, +): value is HandlersOrgKeyCreateResp { + return true; +} + +export function HandlersOrgKeyCreateRespFromJSON( + json: any, +): HandlersOrgKeyCreateResp { + return HandlersOrgKeyCreateRespFromJSONTyped(json, false); +} + +export function HandlersOrgKeyCreateRespFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersOrgKeyCreateResp { + if (json == null) { + return json; + } + return { + created_at: json["created_at"] == null ? undefined : json["created_at"], + expires_at: json["expires_at"] == null ? undefined : json["expires_at"], + id: json["id"] == null ? undefined : json["id"], + name: json["name"] == null ? undefined : json["name"], + org_key: json["org_key"] == null ? undefined : json["org_key"], + org_secret: json["org_secret"] == null ? undefined : json["org_secret"], + scope: json["scope"] == null ? undefined : json["scope"], + }; +} + +export function HandlersOrgKeyCreateRespToJSON( + json: any, +): HandlersOrgKeyCreateResp { + return HandlersOrgKeyCreateRespToJSONTyped(json, false); +} + +export function HandlersOrgKeyCreateRespToJSONTyped( + value?: HandlersOrgKeyCreateResp | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + created_at: value["created_at"], + expires_at: value["expires_at"], + id: value["id"], + name: value["name"], + org_key: value["org_key"], + org_secret: value["org_secret"], + scope: value["scope"], + }; +} diff --git a/sdk/ts/src/models/HandlersOrgUpdateReq.ts b/sdk/ts/src/models/HandlersOrgUpdateReq.ts new file mode 100644 index 0000000..921a0cc --- /dev/null +++ b/sdk/ts/src/models/HandlersOrgUpdateReq.ts @@ -0,0 +1,78 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersOrgUpdateReq + */ +export interface HandlersOrgUpdateReq { + /** + * + * @type {string} + * @memberof HandlersOrgUpdateReq + */ + domain?: string; + /** + * + * @type {string} + * @memberof HandlersOrgUpdateReq + */ + name?: string; +} + +/** + * Check if a given object implements the HandlersOrgUpdateReq interface. + */ +export function instanceOfHandlersOrgUpdateReq( + value: object, +): value is HandlersOrgUpdateReq { + return true; +} + +export function HandlersOrgUpdateReqFromJSON(json: any): HandlersOrgUpdateReq { + return HandlersOrgUpdateReqFromJSONTyped(json, false); +} + +export function HandlersOrgUpdateReqFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersOrgUpdateReq { + if (json == null) { + return json; + } + return { + domain: json["domain"] == null ? undefined : json["domain"], + name: json["name"] == null ? undefined : json["name"], + }; +} + +export function HandlersOrgUpdateReqToJSON(json: any): HandlersOrgUpdateReq { + return HandlersOrgUpdateReqToJSONTyped(json, false); +} + +export function HandlersOrgUpdateReqToJSONTyped( + value?: HandlersOrgUpdateReq | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + domain: value["domain"], + name: value["name"], + }; +} diff --git a/sdk/ts/src/models/HandlersUpdateMeRequest.ts b/sdk/ts/src/models/HandlersUpdateMeRequest.ts new file mode 100644 index 0000000..fbe0a9e --- /dev/null +++ b/sdk/ts/src/models/HandlersUpdateMeRequest.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersUpdateMeRequest + */ +export interface HandlersUpdateMeRequest { + /** + * + * @type {string} + * @memberof HandlersUpdateMeRequest + */ + display_name?: string; +} + +/** + * Check if a given object implements the HandlersUpdateMeRequest interface. + */ +export function instanceOfHandlersUpdateMeRequest( + value: object, +): value is HandlersUpdateMeRequest { + return true; +} + +export function HandlersUpdateMeRequestFromJSON( + json: any, +): HandlersUpdateMeRequest { + return HandlersUpdateMeRequestFromJSONTyped(json, false); +} + +export function HandlersUpdateMeRequestFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersUpdateMeRequest { + if (json == null) { + return json; + } + return { + display_name: + json["display_name"] == null ? undefined : json["display_name"], + }; +} + +export function HandlersUpdateMeRequestToJSON( + json: any, +): HandlersUpdateMeRequest { + return HandlersUpdateMeRequestToJSONTyped(json, false); +} + +export function HandlersUpdateMeRequestToJSONTyped( + value?: HandlersUpdateMeRequest | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + display_name: value["display_name"], + }; +} diff --git a/sdk/ts/src/models/HandlersUserAPIKeyOut.ts b/sdk/ts/src/models/HandlersUserAPIKeyOut.ts new file mode 100644 index 0000000..f111e84 --- /dev/null +++ b/sdk/ts/src/models/HandlersUserAPIKeyOut.ts @@ -0,0 +1,121 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface HandlersUserAPIKeyOut + */ +export interface HandlersUserAPIKeyOut { + /** + * + * @type {string} + * @memberof HandlersUserAPIKeyOut + */ + created_at?: string; + /** + * + * @type {string} + * @memberof HandlersUserAPIKeyOut + */ + expires_at?: string; + /** + * + * @type {string} + * @memberof HandlersUserAPIKeyOut + */ + id?: string; + /** + * + * @type {string} + * @memberof HandlersUserAPIKeyOut + */ + last_used_at?: string; + /** + * + * @type {string} + * @memberof HandlersUserAPIKeyOut + */ + name?: string; + /** + * Shown only on create: + * @type {string} + * @memberof HandlersUserAPIKeyOut + */ + plain?: string; + /** + * "user" + * @type {string} + * @memberof HandlersUserAPIKeyOut + */ + scope?: string; +} + +/** + * Check if a given object implements the HandlersUserAPIKeyOut interface. + */ +export function instanceOfHandlersUserAPIKeyOut( + value: object, +): value is HandlersUserAPIKeyOut { + return true; +} + +export function HandlersUserAPIKeyOutFromJSON( + json: any, +): HandlersUserAPIKeyOut { + return HandlersUserAPIKeyOutFromJSONTyped(json, false); +} + +export function HandlersUserAPIKeyOutFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): HandlersUserAPIKeyOut { + if (json == null) { + return json; + } + return { + created_at: json["created_at"] == null ? undefined : json["created_at"], + expires_at: json["expires_at"] == null ? undefined : json["expires_at"], + id: json["id"] == null ? undefined : json["id"], + last_used_at: + json["last_used_at"] == null ? undefined : json["last_used_at"], + name: json["name"] == null ? undefined : json["name"], + plain: json["plain"] == null ? undefined : json["plain"], + scope: json["scope"] == null ? undefined : json["scope"], + }; +} + +export function HandlersUserAPIKeyOutToJSON(json: any): HandlersUserAPIKeyOut { + return HandlersUserAPIKeyOutToJSONTyped(json, false); +} + +export function HandlersUserAPIKeyOutToJSONTyped( + value?: HandlersUserAPIKeyOut | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + created_at: value["created_at"], + expires_at: value["expires_at"], + id: value["id"], + last_used_at: value["last_used_at"], + name: value["name"], + plain: value["plain"], + scope: value["scope"], + }; +} diff --git a/sdk/ts/src/models/ModelsAPIKey.ts b/sdk/ts/src/models/ModelsAPIKey.ts new file mode 100644 index 0000000..ad325db --- /dev/null +++ b/sdk/ts/src/models/ModelsAPIKey.ts @@ -0,0 +1,164 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface ModelsAPIKey + */ +export interface ModelsAPIKey { + /** + * + * @type {Date} + * @memberof ModelsAPIKey + */ + created_at?: Date; + /** + * + * @type {Date} + * @memberof ModelsAPIKey + */ + expires_at?: Date; + /** + * + * @type {string} + * @memberof ModelsAPIKey + */ + id?: string; + /** + * + * @type {Date} + * @memberof ModelsAPIKey + */ + last_used_at?: Date; + /** + * + * @type {string} + * @memberof ModelsAPIKey + */ + name?: string; + /** + * + * @type {string} + * @memberof ModelsAPIKey + */ + org_id?: string; + /** + * + * @type {string} + * @memberof ModelsAPIKey + */ + prefix?: string; + /** + * + * @type {boolean} + * @memberof ModelsAPIKey + */ + revoked?: boolean; + /** + * + * @type {string} + * @memberof ModelsAPIKey + */ + scope?: string; + /** + * + * @type {Date} + * @memberof ModelsAPIKey + */ + updated_at?: Date; + /** + * + * @type {string} + * @memberof ModelsAPIKey + */ + user_id?: string; +} + +/** + * Check if a given object implements the ModelsAPIKey interface. + */ +export function instanceOfModelsAPIKey(value: object): value is ModelsAPIKey { + return true; +} + +export function ModelsAPIKeyFromJSON(json: any): ModelsAPIKey { + return ModelsAPIKeyFromJSONTyped(json, false); +} + +export function ModelsAPIKeyFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): ModelsAPIKey { + if (json == null) { + return json; + } + return { + created_at: + json["created_at"] == null ? undefined : new Date(json["created_at"]), + expires_at: + json["expires_at"] == null ? undefined : new Date(json["expires_at"]), + id: json["id"] == null ? undefined : json["id"], + last_used_at: + json["last_used_at"] == null ? undefined : new Date(json["last_used_at"]), + name: json["name"] == null ? undefined : json["name"], + org_id: json["org_id"] == null ? undefined : json["org_id"], + prefix: json["prefix"] == null ? undefined : json["prefix"], + revoked: json["revoked"] == null ? undefined : json["revoked"], + scope: json["scope"] == null ? undefined : json["scope"], + updated_at: + json["updated_at"] == null ? undefined : new Date(json["updated_at"]), + user_id: json["user_id"] == null ? undefined : json["user_id"], + }; +} + +export function ModelsAPIKeyToJSON(json: any): ModelsAPIKey { + return ModelsAPIKeyToJSONTyped(json, false); +} + +export function ModelsAPIKeyToJSONTyped( + value?: ModelsAPIKey | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + created_at: + value["created_at"] == null + ? value["created_at"] + : value["created_at"].toISOString(), + expires_at: + value["expires_at"] == null + ? value["expires_at"] + : value["expires_at"].toISOString(), + id: value["id"], + last_used_at: + value["last_used_at"] == null + ? value["last_used_at"] + : value["last_used_at"].toISOString(), + name: value["name"], + org_id: value["org_id"], + prefix: value["prefix"], + revoked: value["revoked"], + scope: value["scope"], + updated_at: + value["updated_at"] == null + ? value["updated_at"] + : value["updated_at"].toISOString(), + user_id: value["user_id"], + }; +} diff --git a/sdk/ts/src/models/ModelsOrganization.ts b/sdk/ts/src/models/ModelsOrganization.ts new file mode 100644 index 0000000..bb81f80 --- /dev/null +++ b/sdk/ts/src/models/ModelsOrganization.ts @@ -0,0 +1,110 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface ModelsOrganization + */ +export interface ModelsOrganization { + /** + * + * @type {Date} + * @memberof ModelsOrganization + */ + created_at?: Date; + /** + * + * @type {string} + * @memberof ModelsOrganization + */ + domain?: string; + /** + * example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + * @type {string} + * @memberof ModelsOrganization + */ + id?: string; + /** + * + * @type {string} + * @memberof ModelsOrganization + */ + name?: string; + /** + * + * @type {Date} + * @memberof ModelsOrganization + */ + updated_at?: Date; +} + +/** + * Check if a given object implements the ModelsOrganization interface. + */ +export function instanceOfModelsOrganization( + value: object, +): value is ModelsOrganization { + return true; +} + +export function ModelsOrganizationFromJSON(json: any): ModelsOrganization { + return ModelsOrganizationFromJSONTyped(json, false); +} + +export function ModelsOrganizationFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): ModelsOrganization { + if (json == null) { + return json; + } + return { + created_at: + json["created_at"] == null ? undefined : new Date(json["created_at"]), + domain: json["domain"] == null ? undefined : json["domain"], + id: json["id"] == null ? undefined : json["id"], + name: json["name"] == null ? undefined : json["name"], + updated_at: + json["updated_at"] == null ? undefined : new Date(json["updated_at"]), + }; +} + +export function ModelsOrganizationToJSON(json: any): ModelsOrganization { + return ModelsOrganizationToJSONTyped(json, false); +} + +export function ModelsOrganizationToJSONTyped( + value?: ModelsOrganization | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + created_at: + value["created_at"] == null + ? value["created_at"] + : value["created_at"].toISOString(), + domain: value["domain"], + id: value["id"], + name: value["name"], + updated_at: + value["updated_at"] == null + ? value["updated_at"] + : value["updated_at"].toISOString(), + }; +} diff --git a/sdk/ts/src/models/ModelsUser.ts b/sdk/ts/src/models/ModelsUser.ts new file mode 100644 index 0000000..2eebc65 --- /dev/null +++ b/sdk/ts/src/models/ModelsUser.ts @@ -0,0 +1,126 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface ModelsUser + */ +export interface ModelsUser { + /** + * + * @type {string} + * @memberof ModelsUser + */ + avatar_url?: string; + /** + * + * @type {Date} + * @memberof ModelsUser + */ + created_at?: Date; + /** + * + * @type {string} + * @memberof ModelsUser + */ + display_name?: string; + /** + * example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + * @type {string} + * @memberof ModelsUser + */ + id?: string; + /** + * + * @type {boolean} + * @memberof ModelsUser + */ + is_disabled?: boolean; + /** + * + * @type {string} + * @memberof ModelsUser + */ + primary_email?: string; + /** + * + * @type {Date} + * @memberof ModelsUser + */ + updated_at?: Date; +} + +/** + * Check if a given object implements the ModelsUser interface. + */ +export function instanceOfModelsUser(value: object): value is ModelsUser { + return true; +} + +export function ModelsUserFromJSON(json: any): ModelsUser { + return ModelsUserFromJSONTyped(json, false); +} + +export function ModelsUserFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): ModelsUser { + if (json == null) { + return json; + } + return { + avatar_url: json["avatar_url"] == null ? undefined : json["avatar_url"], + created_at: + json["created_at"] == null ? undefined : new Date(json["created_at"]), + display_name: + json["display_name"] == null ? undefined : json["display_name"], + id: json["id"] == null ? undefined : json["id"], + is_disabled: json["is_disabled"] == null ? undefined : json["is_disabled"], + primary_email: + json["primary_email"] == null ? undefined : json["primary_email"], + updated_at: + json["updated_at"] == null ? undefined : new Date(json["updated_at"]), + }; +} + +export function ModelsUserToJSON(json: any): ModelsUser { + return ModelsUserToJSONTyped(json, false); +} + +export function ModelsUserToJSONTyped( + value?: ModelsUser | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + avatar_url: value["avatar_url"], + created_at: + value["created_at"] == null + ? value["created_at"] + : value["created_at"].toISOString(), + display_name: value["display_name"], + id: value["id"], + is_disabled: value["is_disabled"], + primary_email: value["primary_email"], + updated_at: + value["updated_at"] == null + ? value["updated_at"] + : value["updated_at"].toISOString(), + }; +} diff --git a/sdk/ts/src/models/ModelsUserEmail.ts b/sdk/ts/src/models/ModelsUserEmail.ts new file mode 100644 index 0000000..a188962 --- /dev/null +++ b/sdk/ts/src/models/ModelsUserEmail.ts @@ -0,0 +1,142 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +import type { ModelsUser } from "./ModelsUser"; +import { + ModelsUserFromJSON, + ModelsUserFromJSONTyped, + ModelsUserToJSON, + ModelsUserToJSONTyped, +} from "./ModelsUser"; + +/** + * + * @export + * @interface ModelsUserEmail + */ +export interface ModelsUserEmail { + /** + * + * @type {Date} + * @memberof ModelsUserEmail + */ + created_at?: Date; + /** + * + * @type {string} + * @memberof ModelsUserEmail + */ + email?: string; + /** + * example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + * @type {string} + * @memberof ModelsUserEmail + */ + id?: string; + /** + * + * @type {boolean} + * @memberof ModelsUserEmail + */ + is_primary?: boolean; + /** + * + * @type {boolean} + * @memberof ModelsUserEmail + */ + is_verified?: boolean; + /** + * + * @type {Date} + * @memberof ModelsUserEmail + */ + updated_at?: Date; + /** + * + * @type {ModelsUser} + * @memberof ModelsUserEmail + */ + user?: ModelsUser; + /** + * + * @type {string} + * @memberof ModelsUserEmail + */ + user_id?: string; +} + +/** + * Check if a given object implements the ModelsUserEmail interface. + */ +export function instanceOfModelsUserEmail( + value: object, +): value is ModelsUserEmail { + return true; +} + +export function ModelsUserEmailFromJSON(json: any): ModelsUserEmail { + return ModelsUserEmailFromJSONTyped(json, false); +} + +export function ModelsUserEmailFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): ModelsUserEmail { + if (json == null) { + return json; + } + return { + created_at: + json["created_at"] == null ? undefined : new Date(json["created_at"]), + email: json["email"] == null ? undefined : json["email"], + id: json["id"] == null ? undefined : json["id"], + is_primary: json["is_primary"] == null ? undefined : json["is_primary"], + is_verified: json["is_verified"] == null ? undefined : json["is_verified"], + updated_at: + json["updated_at"] == null ? undefined : new Date(json["updated_at"]), + user: json["user"] == null ? undefined : ModelsUserFromJSON(json["user"]), + user_id: json["user_id"] == null ? undefined : json["user_id"], + }; +} + +export function ModelsUserEmailToJSON(json: any): ModelsUserEmail { + return ModelsUserEmailToJSONTyped(json, false); +} + +export function ModelsUserEmailToJSONTyped( + value?: ModelsUserEmail | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + created_at: + value["created_at"] == null + ? value["created_at"] + : value["created_at"].toISOString(), + email: value["email"], + id: value["id"], + is_primary: value["is_primary"], + is_verified: value["is_verified"], + updated_at: + value["updated_at"] == null + ? value["updated_at"] + : value["updated_at"].toISOString(), + user: ModelsUserToJSON(value["user"]), + user_id: value["user_id"], + }; +} diff --git a/sdk/ts/src/models/UtilsErrorResponse.ts b/sdk/ts/src/models/UtilsErrorResponse.ts new file mode 100644 index 0000000..5e83fd3 --- /dev/null +++ b/sdk/ts/src/models/UtilsErrorResponse.ts @@ -0,0 +1,80 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface UtilsErrorResponse + */ +export interface UtilsErrorResponse { + /** + * A machine-readable error code, e.g. "validation_error" + * example: validation_error + * @type {string} + * @memberof UtilsErrorResponse + */ + code?: string; + /** + * Human-readable message + * example: slug is required + * @type {string} + * @memberof UtilsErrorResponse + */ + message?: string; +} + +/** + * Check if a given object implements the UtilsErrorResponse interface. + */ +export function instanceOfUtilsErrorResponse( + value: object, +): value is UtilsErrorResponse { + return true; +} + +export function UtilsErrorResponseFromJSON(json: any): UtilsErrorResponse { + return UtilsErrorResponseFromJSONTyped(json, false); +} + +export function UtilsErrorResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): UtilsErrorResponse { + if (json == null) { + return json; + } + return { + code: json["code"] == null ? undefined : json["code"], + message: json["message"] == null ? undefined : json["message"], + }; +} + +export function UtilsErrorResponseToJSON(json: any): UtilsErrorResponse { + return UtilsErrorResponseToJSONTyped(json, false); +} + +export function UtilsErrorResponseToJSONTyped( + value?: UtilsErrorResponse | null, + ignoreDiscriminator: boolean = false, +): any { + if (value == null) { + return value; + } + + return { + code: value["code"], + message: value["message"], + }; +} diff --git a/sdk/ts/src/models/index.ts b/sdk/ts/src/models/index.ts new file mode 100644 index 0000000..1f95a32 --- /dev/null +++ b/sdk/ts/src/models/index.ts @@ -0,0 +1,32 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from "./DtoAuthStartResponse"; +export * from "./DtoCreateSSHRequest"; +export * from "./DtoCreateServerRequest"; +export * from "./DtoCreateTaintRequest"; +export * from "./DtoJWK"; +export * from "./DtoJWKS"; +export * from "./DtoLogoutRequest"; +export * from "./DtoRefreshRequest"; +export * from "./DtoServerResponse"; +export * from "./DtoSshResponse"; +export * from "./DtoSshRevealResponse"; +export * from "./DtoTaintResponse"; +export * from "./DtoTokenPair"; +export * from "./DtoUpdateServerRequest"; +export * from "./DtoUpdateTaintRequest"; +export * from "./HandlersCreateUserKeyRequest"; +export * from "./HandlersMeResponse"; +export * from "./HandlersMemberOut"; +export * from "./HandlersMemberUpsertReq"; +export * from "./HandlersOrgCreateReq"; +export * from "./HandlersOrgKeyCreateReq"; +export * from "./HandlersOrgKeyCreateResp"; +export * from "./HandlersOrgUpdateReq"; +export * from "./HandlersUpdateMeRequest"; +export * from "./HandlersUserAPIKeyOut"; +export * from "./ModelsAPIKey"; +export * from "./ModelsOrganization"; +export * from "./ModelsUser"; +export * from "./ModelsUserEmail"; +export * from "./UtilsErrorResponse"; diff --git a/sdk/ts/src/runtime.ts b/sdk/ts/src/runtime.ts new file mode 100644 index 0000000..71111cd --- /dev/null +++ b/sdk/ts/src/runtime.ts @@ -0,0 +1,530 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * AutoGlue API + * API for managing K3s clusters across cloud providers + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +export const BASE_PATH = "http://localhost:8080/api/v1".replace(/\/+$/, ""); + +export interface ConfigurationParameters { + basePath?: string; // override base path + fetchApi?: FetchAPI; // override for fetch implementation + middleware?: Middleware[]; // middleware to apply before/after fetch requests + queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings + username?: string; // parameter for basic security + password?: string; // parameter for basic security + apiKey?: + | string + | Promise + | ((name: string) => string | Promise); // parameter for apiKey security + accessToken?: + | string + | Promise + | ((name?: string, scopes?: string[]) => string | Promise); // parameter for oauth2 security + headers?: HTTPHeaders; //header params we want to use on every request + credentials?: RequestCredentials; //value for the credentials param we want to use on each request +} + +export class Configuration { + constructor(private configuration: ConfigurationParameters = {}) {} + + set config(configuration: Configuration) { + this.configuration = configuration; + } + + get basePath(): string { + return this.configuration.basePath != null + ? this.configuration.basePath + : BASE_PATH; + } + + get fetchApi(): FetchAPI | undefined { + return this.configuration.fetchApi; + } + + get middleware(): Middleware[] { + return this.configuration.middleware || []; + } + + get queryParamsStringify(): (params: HTTPQuery) => string { + return this.configuration.queryParamsStringify || querystring; + } + + get username(): string | undefined { + return this.configuration.username; + } + + get password(): string | undefined { + return this.configuration.password; + } + + get apiKey(): ((name: string) => string | Promise) | undefined { + const apiKey = this.configuration.apiKey; + if (apiKey) { + return typeof apiKey === "function" ? apiKey : () => apiKey; + } + return undefined; + } + + get accessToken(): + | ((name?: string, scopes?: string[]) => string | Promise) + | undefined { + const accessToken = this.configuration.accessToken; + if (accessToken) { + return typeof accessToken === "function" + ? accessToken + : async () => accessToken; + } + return undefined; + } + + get headers(): HTTPHeaders | undefined { + return this.configuration.headers; + } + + get credentials(): RequestCredentials | undefined { + return this.configuration.credentials; + } +} + +export const DefaultConfig = new Configuration(); + +/** + * This is the base class for all generated API classes. + */ +export class BaseAPI { + private static readonly jsonRegex = new RegExp( + "^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$", + "i", + ); + private middleware: Middleware[]; + + constructor(protected configuration = DefaultConfig) { + this.middleware = configuration.middleware; + } + + withMiddleware(this: T, ...middlewares: Middleware[]) { + const next = this.clone(); + next.middleware = next.middleware.concat(...middlewares); + return next; + } + + withPreMiddleware( + this: T, + ...preMiddlewares: Array + ) { + const middlewares = preMiddlewares.map((pre) => ({ pre })); + return this.withMiddleware(...middlewares); + } + + withPostMiddleware( + this: T, + ...postMiddlewares: Array + ) { + const middlewares = postMiddlewares.map((post) => ({ post })); + return this.withMiddleware(...middlewares); + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + protected isJsonMime(mime: string | null | undefined): boolean { + if (!mime) { + return false; + } + return BaseAPI.jsonRegex.test(mime); + } + + protected async request( + context: RequestOpts, + initOverrides?: RequestInit | InitOverrideFunction, + ): Promise { + const { url, init } = await this.createFetchParams(context, initOverrides); + const response = await this.fetchApi(url, init); + if (response && response.status >= 200 && response.status < 300) { + return response; + } + throw new ResponseError(response, "Response returned an error code"); + } + + private async createFetchParams( + context: RequestOpts, + initOverrides?: RequestInit | InitOverrideFunction, + ) { + let url = this.configuration.basePath + context.path; + if ( + context.query !== undefined && + Object.keys(context.query).length !== 0 + ) { + // only add the querystring to the URL if there are query parameters. + // this is done to avoid urls ending with a "?" character which buggy webservers + // do not handle correctly sometimes. + url += "?" + this.configuration.queryParamsStringify(context.query); + } + + const headers = Object.assign( + {}, + this.configuration.headers, + context.headers, + ); + Object.keys(headers).forEach((key) => + headers[key] === undefined ? delete headers[key] : {}, + ); + + const initOverrideFn = + typeof initOverrides === "function" + ? initOverrides + : async () => initOverrides; + + const initParams = { + method: context.method, + headers, + body: context.body, + credentials: this.configuration.credentials, + }; + + const overriddenInit: RequestInit = { + ...initParams, + ...(await initOverrideFn({ + init: initParams, + context, + })), + }; + + let body: any; + if ( + isFormData(overriddenInit.body) || + overriddenInit.body instanceof URLSearchParams || + isBlob(overriddenInit.body) + ) { + body = overriddenInit.body; + } else if (this.isJsonMime(headers["Content-Type"])) { + body = JSON.stringify(overriddenInit.body); + } else { + body = overriddenInit.body; + } + + const init: RequestInit = { + ...overriddenInit, + body, + }; + + return { url, init }; + } + + private fetchApi = async (url: string, init: RequestInit) => { + let fetchParams = { url, init }; + for (const middleware of this.middleware) { + if (middleware.pre) { + fetchParams = + (await middleware.pre({ + fetch: this.fetchApi, + ...fetchParams, + })) || fetchParams; + } + } + let response: Response | undefined = undefined; + try { + response = await (this.configuration.fetchApi || fetch)( + fetchParams.url, + fetchParams.init, + ); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = + (await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + })) || response; + } + } + if (response === undefined) { + if (e instanceof Error) { + throw new FetchError( + e, + "The request failed and the interceptors did not return an alternative response", + ); + } else { + throw e; + } + } + } + for (const middleware of this.middleware) { + if (middleware.post) { + response = + (await middleware.post({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + response: response.clone(), + })) || response; + } + } + return response; + }; + + /** + * Create a shallow clone of `this` by constructing a new instance + * and then shallow cloning data members. + */ + private clone(this: T): T { + const constructor = this.constructor as any; + const next = new constructor(this.configuration); + next.middleware = this.middleware.slice(); + return next; + } +} + +function isBlob(value: any): value is Blob { + return typeof Blob !== "undefined" && value instanceof Blob; +} + +function isFormData(value: any): value is FormData { + return typeof FormData !== "undefined" && value instanceof FormData; +} + +export class ResponseError extends Error { + override name: "ResponseError" = "ResponseError"; + constructor( + public response: Response, + msg?: string, + ) { + super(msg); + } +} + +export class FetchError extends Error { + override name: "FetchError" = "FetchError"; + constructor( + public cause: Error, + msg?: string, + ) { + super(msg); + } +} + +export class RequiredError extends Error { + override name: "RequiredError" = "RequiredError"; + constructor( + public field: string, + msg?: string, + ) { + super(msg); + } +} + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export type FetchAPI = WindowOrWorkerGlobalScope["fetch"]; + +export type Json = any; +export type HTTPMethod = + | "GET" + | "POST" + | "PUT" + | "PATCH" + | "DELETE" + | "OPTIONS" + | "HEAD"; +export type HTTPHeaders = { [key: string]: string }; +export type HTTPQuery = { + [key: string]: + | string + | number + | null + | boolean + | Array + | Set + | HTTPQuery; +}; +export type HTTPBody = Json | FormData | URLSearchParams; +export type HTTPRequestInit = { + headers?: HTTPHeaders; + method: HTTPMethod; + credentials?: RequestCredentials; + body?: HTTPBody; +}; +export type ModelPropertyNaming = + | "camelCase" + | "snake_case" + | "PascalCase" + | "original"; + +export type InitOverrideFunction = (requestContext: { + init: HTTPRequestInit; + context: RequestOpts; +}) => Promise; + +export interface FetchParams { + url: string; + init: RequestInit; +} + +export interface RequestOpts { + path: string; + method: HTTPMethod; + headers: HTTPHeaders; + query?: HTTPQuery; + body?: HTTPBody; +} + +export function querystring(params: HTTPQuery, prefix: string = ""): string { + return Object.keys(params) + .map((key) => querystringSingleKey(key, params[key], prefix)) + .filter((part) => part.length > 0) + .join("&"); +} + +function querystringSingleKey( + key: string, + value: + | string + | number + | null + | undefined + | boolean + | Array + | Set + | HTTPQuery, + keyPrefix: string = "", +): string { + const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key); + if (value instanceof Array) { + const multiValue = value + .map((singleValue) => encodeURIComponent(String(singleValue))) + .join(`&${encodeURIComponent(fullKey)}=`); + return `${encodeURIComponent(fullKey)}=${multiValue}`; + } + if (value instanceof Set) { + const valueAsArray = Array.from(value); + return querystringSingleKey(key, valueAsArray, keyPrefix); + } + if (value instanceof Date) { + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`; + } + if (value instanceof Object) { + return querystring(value as HTTPQuery, fullKey); + } + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; +} + +export function exists(json: any, key: string) { + const value = json[key]; + return value !== null && value !== undefined; +} + +export function mapValues(data: any, fn: (item: any) => any) { + const result: { [key: string]: any } = {}; + for (const key of Object.keys(data)) { + result[key] = fn(data[key]); + } + return result; +} + +export function canConsumeForm(consumes: Consume[]): boolean { + for (const consume of consumes) { + if ("multipart/form-data" === consume.contentType) { + return true; + } + } + return false; +} + +export interface Consume { + contentType: string; +} + +export interface RequestContext { + fetch: FetchAPI; + url: string; + init: RequestInit; +} + +export interface ResponseContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + response: Response; +} + +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + +export interface Middleware { + pre?(context: RequestContext): Promise; + post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; +} + +export interface ApiResponse { + raw: Response; + value(): Promise; +} + +export interface ResponseTransformer { + (json: any): T; +} + +export class JSONApiResponse { + constructor( + public raw: Response, + private transformer: ResponseTransformer = (jsonValue: any) => jsonValue, + ) {} + + async value(): Promise { + return this.transformer(await this.raw.json()); + } +} + +export class VoidApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return undefined; + } +} + +export class BlobApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.blob(); + } +} + +export class TextApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.text(); + } +} diff --git a/sdk/ts/tsconfig.esm.json b/sdk/ts/tsconfig.esm.json new file mode 100644 index 0000000..2c0331c --- /dev/null +++ b/sdk/ts/tsconfig.esm.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "esnext", + "outDir": "dist/esm" + } +} diff --git a/sdk/ts/tsconfig.json b/sdk/ts/tsconfig.json new file mode 100644 index 0000000..e69c9c2 --- /dev/null +++ b/sdk/ts/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "declaration": true, + "target": "es6", + "module": "commonjs", + "moduleResolution": "node", + "outDir": "dist", + "typeRoots": ["node_modules/@types"] + }, + "exclude": ["dist", "node_modules"] +} diff --git a/terraform-provider-autoglue/Makefile b/terraform-provider-autoglue/Makefile new file mode 100644 index 0000000..efe381a --- /dev/null +++ b/terraform-provider-autoglue/Makefile @@ -0,0 +1,23 @@ +BIN ?= terraform-provider-autoglue +VER ?= 0.0.1 +OS ?= $(shell uname -s | tr '[:upper:]' '[:lower:]') +ARCH ?= $(shell uname -m | sed 's/x86_64/amd64/;s/arm64/arm64/') + +.PHONY: build tidy dev clean + +build: + go build -o $(BIN) . + +tidy: + go mod tidy + +dev: + @echo "Installing dev provider v$(VER) for $(OS)_$(ARCH)..." + @DST="$${HOME}/.terraform.d/plugins/glueops/autoglue/autoglue/$(VER)/$(OS)_$(ARCH)"; \ + mkdir -p "$$DST"; \ + go build -o "$$DST/terraform-provider-autoglue_v$(VER)" .; \ + echo "Provider installed to $$DST"; \ + echo "Run: terraform init -upgrade" + +clean: + rm -f $(BIN) diff --git a/terraform-provider-autoglue/go.mod b/terraform-provider-autoglue/go.mod new file mode 100644 index 0000000..88be9f8 --- /dev/null +++ b/terraform-provider-autoglue/go.mod @@ -0,0 +1,36 @@ +module github.com/glueops/terraform-provider-gsot + +go 1.25.3 + +require ( + github.com/glueops/autoglue-sdk v0.0.0-00010101000000-000000000000 + github.com/hashicorp/terraform-plugin-framework v1.16.1 + github.com/hashicorp/terraform-plugin-framework-validators v0.19.0 +) + +require ( + github.com/fatih/color v1.15.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/go-plugin v1.7.0 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hashicorp/terraform-plugin-go v0.29.0 // indirect + github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect + github.com/hashicorp/terraform-registry-address v0.4.0 // indirect + github.com/hashicorp/terraform-svchost v0.1.1 // indirect + github.com/hashicorp/yamux v0.1.2 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect + google.golang.org/grpc v1.75.1 // indirect + google.golang.org/protobuf v1.36.9 // indirect +) + +replace github.com/glueops/autoglue-sdk => ../sdk/go diff --git a/terraform-provider-autoglue/go.sum b/terraform-provider-autoglue/go.sum new file mode 100644 index 0000000..e1c012b --- /dev/null +++ b/terraform-provider-autoglue/go.sum @@ -0,0 +1,101 @@ +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= +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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= +github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/terraform-plugin-framework v1.16.1 h1:1+zwFm3MEqd/0K3YBB2v9u9DtyYHyEuhVOfeIXbteWA= +github.com/hashicorp/terraform-plugin-framework v1.16.1/go.mod h1:0xFOxLy5lRzDTayc4dzK/FakIgBhNf/lC4499R9cV4Y= +github.com/hashicorp/terraform-plugin-framework-validators v0.19.0 h1:Zz3iGgzxe/1XBkooZCewS0nJAaCFPFPHdNJd8FgE4Ow= +github.com/hashicorp/terraform-plugin-framework-validators v0.19.0/go.mod h1:GBKTNGbGVJohU03dZ7U8wHqc2zYnMUawgCN+gC0itLc= +github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU= +github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM= +github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= +github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk= +github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE= +github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= +github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= +google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/terraform-provider-autoglue/internal/provider/client.go b/terraform-provider-autoglue/internal/provider/client.go new file mode 100644 index 0000000..849d03c --- /dev/null +++ b/terraform-provider-autoglue/internal/provider/client.go @@ -0,0 +1,78 @@ +package provider + +import ( + "context" + "net/http" + + "github.com/glueops/autoglue-sdk" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +type Client struct { + SDK *autoglue.APIClient +} + +func NewClient(_ context.Context, cfg providerModel) (*Client, diag.Diagnostics) { + var diags diag.Diagnostics + + conf := autoglue.NewConfiguration() + conf.Servers = autoglue.ServerConfigurations{{URL: cfg.Addr.ValueString()}} + + // Attach auth headers for *every* request + rt := http.DefaultTransport + conf.HTTPClient = &http.Client{ + Transport: headerRoundTripper{ + under: rt, + bearer: strOrEmpty(cfg.Bearer), + apiKey: strOrEmpty(cfg.APIKey), + orgKey: strOrEmpty(cfg.OrgKey), + orgSecret: strOrEmpty(cfg.OrgSecret), + orgID: strOrEmpty(cfg.OrgID), + }, + } + + return &Client{SDK: autoglue.NewAPIClient(conf)}, diags +} + +type headerRoundTripper struct { + under http.RoundTripper + bearer string + apiKey string + orgKey string + orgSecret string + orgID string +} + +func (h headerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + // Bearer -> Authorization + if h.bearer != "" { + req.Header.Set("Authorization", "Bearer "+h.bearer) + } + // User API Key + if h.apiKey != "" { + req.Header.Set("X-API-KEY", h.apiKey) + } + // Org key/secret + if h.orgKey != "" { + req.Header.Set("X-ORG-KEY", h.orgKey) + } + if h.orgSecret != "" { + req.Header.Set("X-ORG-SECRET", h.orgSecret) + } + // Org selection header (user or key where needed) + if h.orgID != "" { + req.Header.Set("X-Org-ID", h.orgID) + } + return h.under.RoundTrip(req) +} + +func strOrEmpty(v interface { + IsNull() bool + IsUnknown() bool + ValueString() string +}) string { + if v.IsNull() || v.IsUnknown() { + return "" + } + return v.ValueString() +} diff --git a/terraform-provider-autoglue/internal/provider/config.go b/terraform-provider-autoglue/internal/provider/config.go new file mode 100644 index 0000000..506ed78 --- /dev/null +++ b/terraform-provider-autoglue/internal/provider/config.go @@ -0,0 +1,99 @@ +package provider + +import ( + "context" + "os" + + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/provider" + pschema "github.com/hashicorp/terraform-plugin-framework/provider/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type providerModel struct { + Addr types.String `tfsdk:"addr"` + Bearer types.String `tfsdk:"bearer"` + APIKey types.String `tfsdk:"api_key"` + OrgKey types.String `tfsdk:"org_key"` + OrgSecret types.String `tfsdk:"org_secret"` + OrgID types.String `tfsdk:"org_id"` +} + +func providerConfigSchema() map[string]pschema.Attribute { + return map[string]pschema.Attribute{ + "addr": pschema.StringAttribute{ + Optional: true, + Description: "Base URL to the autoglue API (e.g. https://gsot.example.com/api/v1). Defaults to http://localhost:8080/api/v1.", + }, + "bearer": pschema.StringAttribute{ + Optional: true, + Sensitive: true, + Description: "Bearer token (user access token).", + }, + "api_key": pschema.StringAttribute{ + Optional: true, + Sensitive: true, + Description: "User API key for key-only auth.", + }, + "org_key": pschema.StringAttribute{ + Optional: true, + Sensitive: true, + Description: "Org-scoped key for machine auth.", + }, + "org_secret": pschema.StringAttribute{ + Optional: true, + Sensitive: true, + Description: "Org-scoped secret for machine auth.", + }, + "org_id": pschema.StringAttribute{ + Optional: true, + Description: "Organization ID (UUID). Required for user/bearer and user API key auth unless single-org membership. Omitted for org key/secret (derived server-side).", + Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, + }, + } +} + +func readConfig(ctx context.Context, req provider.ConfigureRequest) (providerModel, diag.Diagnostics) { + var cfg providerModel + var diags diag.Diagnostics + + req.Config.Get(ctx, &cfg) + + if cfg.Addr.IsNull() || cfg.Addr.IsUnknown() { + if v := os.Getenv("AUTOGLUE_ADDR"); v != "" { + cfg.Addr = types.StringValue(v) + } else { + cfg.Addr = types.StringValue("http://localhost:8080/api/v1") + } + } + if cfg.Bearer.IsNull() || cfg.Bearer.IsUnknown() { + if v := os.Getenv("AUTOGLUE_TOKEN"); v != "" { + cfg.Bearer = types.StringValue(v) + } + } + if cfg.APIKey.IsNull() || cfg.APIKey.IsUnknown() { + if v := os.Getenv("AUTOGLUE_API_KEY"); v != "" { + cfg.APIKey = types.StringValue(v) + } + } + if cfg.OrgKey.IsNull() || cfg.OrgKey.IsUnknown() { + if v := os.Getenv("AUTOGLUE_ORG_KEY"); v != "" { + cfg.OrgKey = types.StringValue(v) + } + } + if cfg.OrgSecret.IsNull() || cfg.OrgSecret.IsUnknown() { + if v := os.Getenv("AUTOGLUE_ORG_SECRET"); v != "" { + cfg.OrgSecret = types.StringValue(v) + } + } + if cfg.OrgID.IsNull() || cfg.OrgID.IsUnknown() { + if v := os.Getenv("AUTOGLUE_ORG_ID"); v != "" { + cfg.OrgID = types.StringValue(v) + } else { + cfg.OrgID = types.StringNull() + } + } + return cfg, diags +} diff --git a/terraform-provider-autoglue/internal/provider/datasource_ssh.go b/terraform-provider-autoglue/internal/provider/datasource_ssh.go new file mode 100644 index 0000000..5e4707a --- /dev/null +++ b/terraform-provider-autoglue/internal/provider/datasource_ssh.go @@ -0,0 +1,121 @@ +package provider + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var _ datasource.DataSource = &SshDataSource{} +var _ datasource.DataSourceWithConfigure = &SshDataSource{} + +type SshDataSource struct{ client *Client } + +func NewSshDataSource() datasource.DataSource { return &SshDataSource{} } + +type sshDSModel struct { + NameContains types.String `tfsdk:"name_contains"` + Fingerprint types.String `tfsdk:"fingerprint"` + Keys []sshItem `tfsdk:"keys"` +} + +type sshItem struct { + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + PublicKey types.String `tfsdk:"public_key"` + Fingerprint types.String `tfsdk:"fingerprint"` + CreatedAt types.String `tfsdk:"created_at"` + UpdatedAt types.String `tfsdk:"updated_at"` +} + +func (d *SshDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_ssh_keys" +} + +func (d *SshDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = dschema.Schema{ + Attributes: map[string]dschema.Attribute{ + "name_contains": dschema.StringAttribute{ + Optional: true, + Description: "Filter by substring of name (client-side).", + }, + "fingerprint": dschema.StringAttribute{ + Optional: true, + Description: "Filter by exact fingerprint (client-side).", + }, + "keys": dschema.ListNestedAttribute{ + Computed: true, + Description: "SSH keys", + NestedObject: dschema.NestedAttributeObject{ + Attributes: map[string]dschema.Attribute{ + "id": dschema.StringAttribute{Computed: true}, + "name": dschema.StringAttribute{Computed: true}, + "public_key": dschema.StringAttribute{Computed: true}, + "fingerprint": dschema.StringAttribute{Computed: true}, + "created_at": dschema.StringAttribute{Computed: true}, + "updated_at": dschema.StringAttribute{Computed: true}, + }, + }, + }, + }, + } +} + +func (d *SshDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + d.client = req.ProviderData.(*Client) +} + +func (d *SshDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + if d.client == nil || d.client.SDK == nil { + resp.Diagnostics.AddError("Client not configured", "Provider configuration missing") + return + } + + var conf sshDSModel + resp.Diagnostics.Append(req.Config.Get(ctx, &conf)...) + if resp.Diagnostics.HasError() { + return + } + + items, httpResp, err := d.client.SDK.SshAPI.ListPublicSshKeys(ctx).Execute() + if err != nil { + resp.Diagnostics.AddError("List ssh keys failed", fmt.Sprintf("%v", httpErr(err, httpResp))) + return + } + + nc := strings.ToLower(conf.NameContains.ValueString()) + fp := conf.Fingerprint.ValueString() + out := sshDSModel{NameContains: conf.NameContains, Fingerprint: conf.Fingerprint} + out.Keys = make([]sshItem, 0, len(items)) + + for _, s := range items { + name := "" + if s.Name != nil { + name = *s.Name + } + if nc != "" && !strings.Contains(strings.ToLower(name), nc) { + continue + } + if fp != "" && (s.Fingerprint == nil || *s.Fingerprint != fp) { + continue + } + + out.Keys = append(out.Keys, sshItem{ + ID: types.StringPointerValue(s.Id), + Name: types.StringPointerValue(s.Name), + PublicKey: types.StringPointerValue(s.PublicKey), + Fingerprint: types.StringPointerValue(s.Fingerprint), + CreatedAt: types.StringPointerValue(s.CreatedAt), + UpdatedAt: types.StringPointerValue(s.UpdatedAt), + }) + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &out)...) +} diff --git a/terraform-provider-autoglue/internal/provider/http_err.go b/terraform-provider-autoglue/internal/provider/http_err.go new file mode 100644 index 0000000..1c7a802 --- /dev/null +++ b/terraform-provider-autoglue/internal/provider/http_err.go @@ -0,0 +1,20 @@ +package provider + +import ( + "fmt" + "io" + "net/http" +) + +func httpErr(err error, resp *http.Response) string { + if resp == nil { + return err.Error() + } + defer resp.Body.Close() + b, _ := io.ReadAll(resp.Body) + return fmt.Sprintf("status=%d: %s (body=%s)", resp.StatusCode, resp.Status, string(b)) +} + +func isNotFound(resp *http.Response) bool { + return resp != nil && resp.StatusCode == http.StatusNotFound +} diff --git a/terraform-provider-autoglue/internal/provider/num.go b/terraform-provider-autoglue/internal/provider/num.go new file mode 100644 index 0000000..3c4a2d4 --- /dev/null +++ b/terraform-provider-autoglue/internal/provider/num.go @@ -0,0 +1,14 @@ +package provider + +import "math" + +func round6(x float64) float64 { + return math.Round(x*1e6) / 1e6 +} + +func f32ptrToTF64(v *float32) float64 { + if v == nil { + return 0 + } + return round6(float64(*v)) +} diff --git a/terraform-provider-autoglue/internal/provider/provider.go b/terraform-provider-autoglue/internal/provider/provider.go new file mode 100644 index 0000000..4d659f0 --- /dev/null +++ b/terraform-provider-autoglue/internal/provider/provider.go @@ -0,0 +1,58 @@ +package provider + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/provider" + pschema "github.com/hashicorp/terraform-plugin-framework/provider/schema" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +var _ provider.Provider = &AutoglueProvider{} + +func New() provider.Provider { return &AutoglueProvider{} } + +type AutoglueProvider struct { + version string +} + +func (p *AutoglueProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) { + resp.TypeName = "autoglue" + resp.Version = p.version +} + +func (p *AutoglueProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) { + resp.Schema = pschema.Schema{ + Attributes: providerConfigSchema(), + } +} + +func (p *AutoglueProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { + cfg, diags := readConfig(ctx, req) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, diags := NewClient(ctx, cfg) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + resp.DataSourceData = client + resp.ResourceData = client +} + +func (p *AutoglueProvider) DataSources(_ context.Context) []func() datasource.DataSource { + return []func() datasource.DataSource{ + NewSshDataSource, + } +} + +func (p *AutoglueProvider) Resources(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + NewSshResource, + } +} diff --git a/terraform-provider-autoglue/internal/provider/resource_ssh.go b/terraform-provider-autoglue/internal/provider/resource_ssh.go new file mode 100644 index 0000000..bf019ef --- /dev/null +++ b/terraform-provider-autoglue/internal/provider/resource_ssh.go @@ -0,0 +1,230 @@ +package provider + +import ( + "context" + "fmt" + + "github.com/glueops/autoglue-sdk" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + rschema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var _ resource.Resource = &SshResource{} +var _ resource.ResourceWithConfigure = &SshResource{} +var _ resource.ResourceWithImportState = &SshResource{} + +type SshResource struct{ client *Client } + +func NewSshResource() resource.Resource { return &SshResource{} } + +type sshResModel struct { + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Comment types.String `tfsdk:"comment"` + Type types.String `tfsdk:"type"` + Bits types.Int64 `tfsdk:"bits"` + PublicKey types.String `tfsdk:"public_key"` + Fingerprint types.String `tfsdk:"fingerprint"` + CreatedAt types.String `tfsdk:"created_at"` + UpdatedAt types.String `tfsdk:"updated_at"` + PrivateKeyPEM types.String `tfsdk:"private_key_pem"` // not populated by resource +} + +func (r *SshResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_ssh_key" +} + +func (r *SshResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = rschema.Schema{ + Attributes: map[string]rschema.Attribute{ + "id": rschema.StringAttribute{ + Computed: true, + Description: "SSH key ID (UUID)", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "name": rschema.StringAttribute{ + Required: true, + Description: "Display name", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "comment": rschema.StringAttribute{ + Required: true, + Description: "Comment appended to authorized key", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "type": rschema.StringAttribute{ + Optional: true, + Description: "Key type: rsa or ed25519 (default rsa)", + Validators: []validator.String{ + stringvalidator.OneOf("rsa", "ed25519", ""), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "bits": rschema.Int64Attribute{ + Optional: true, + Description: "RSA key size (2048/3072/4096). Ignored for ed25519.", + Validators: []validator.Int64{ + int64validator.OneOf(2048, 3072, 4096), + }, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "public_key": rschema.StringAttribute{ + Computed: true, + Description: "OpenSSH authorized key", + }, + "fingerprint": rschema.StringAttribute{ + Computed: true, + Description: "SHA256 fingerprint", + }, + "created_at": rschema.StringAttribute{ + Computed: true, + Description: "Creation time (RFC3339, UTC)", + }, + "updated_at": rschema.StringAttribute{ + Computed: true, + Description: "Update time (RFC3339, UTC)", + }, + "private_key_pem": rschema.StringAttribute{ + Computed: true, + Sensitive: true, + Description: "Private key PEM (resource doesn’t reveal; stays empty).", + }, + }, + } +} + +func (r *SshResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + r.client = req.ProviderData.(*Client) +} + +func (r *SshResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + if r.client == nil || r.client.SDK == nil { + resp.Diagnostics.AddError("Client not configured", "Provider configuration missing") + return + } + + var plan sshResModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + body := autoglue.DtoCreateSSHRequest{ + Name: plan.Name.ValueStringPointer(), + Comment: plan.Comment.ValueStringPointer(), + } + if t := plan.Type.ValueString(); t != "" { + body.Type = &t + } + if !plan.Bits.IsNull() && !plan.Bits.IsUnknown() { + b := int32(plan.Bits.ValueInt64()) + body.Bits = &b + } + + created, httpResp, err := r.client.SDK.SshAPI.CreateSSHKey(ctx).Body(body).Execute() + if err != nil { + resp.Diagnostics.AddError("Create ssh key failed", fmt.Sprintf("%v", httpErr(err, httpResp))) + return + } + + state := sshResModel{ + ID: types.StringPointerValue(created.Id), + Name: types.StringPointerValue(created.Name), + Comment: plan.Comment, + Type: plan.Type, + Bits: plan.Bits, + PublicKey: types.StringPointerValue(created.PublicKey), + Fingerprint: types.StringPointerValue(created.Fingerprint), + CreatedAt: types.StringPointerValue(created.CreatedAt), + UpdatedAt: types.StringPointerValue(created.UpdatedAt), + // PrivateKeyPEM left empty (no reveal on resource) + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *SshResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + if r.client == nil || r.client.SDK == nil { + resp.Diagnostics.AddError("Client not configured", "Provider configuration missing") + return + } + + var state sshResModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + got, httpResp, err := r.client.SDK.SshAPI.GetSSHKey(ctx, state.ID.ValueString()).Execute() + if err != nil { + if isNotFound(httpResp) { + resp.State.RemoveResource(ctx) + return + } + resp.Diagnostics.AddError("Read ssh key failed", fmt.Sprintf("%v", httpErr(err, httpResp))) + return + } + + // Map from flat fields on DtoSshRevealResponse + state.Name = types.StringPointerValue(got.Name) + state.PublicKey = types.StringPointerValue(got.PublicKey) + state.Fingerprint = types.StringPointerValue(got.Fingerprint) + state.CreatedAt = types.StringPointerValue(got.CreatedAt) + state.UpdatedAt = types.StringPointerValue(got.UpdatedAt) + // We intentionally do NOT set PrivateKeyPEM here (resource doesn't reveal) + + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *SshResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + // All changes are RequiresReplace; no server-side update. + var state sshResModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *SshResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + if r.client == nil || r.client.SDK == nil { + resp.Diagnostics.AddError("Client not configured", "Provider configuration missing") + return + } + + var state sshResModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + _, httpResp, err := r.client.SDK.SshAPI.DeleteSSHKey(ctx, state.ID.ValueString()).Execute() + if err != nil && !isNotFound(httpResp) { + resp.Diagnostics.AddError("Delete ssh key failed", fmt.Sprintf("%v", httpErr(err, httpResp))) + } +} + +func (r *SshResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), req.ID)...) +} diff --git a/terraform-provider-autoglue/main.go b/terraform-provider-autoglue/main.go new file mode 100644 index 0000000..3725550 --- /dev/null +++ b/terraform-provider-autoglue/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "context" + "flag" + + "github.com/glueops/terraform-provider-gsot/internal/provider" + "github.com/hashicorp/terraform-plugin-framework/providerserver" +) + +var ( + version = "0.10.0" +) + +func main() { + var debug bool + + flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve") + flag.Parse() + + providerserver.Serve(context.Background(), provider.New, providerserver.ServeOpts{ + Address: "terraform.gpkg.io/glueops/autoglue", //"registry.terraform.io/glueops/autoglue", + Debug: debug, + }) +} diff --git a/terraform/envs/dev/.terraform.lock.hcl b/terraform/envs/dev/.terraform.lock.hcl new file mode 100644 index 0000000..68d22e7 --- /dev/null +++ b/terraform/envs/dev/.terraform.lock.hcl @@ -0,0 +1,63 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "glueops/autoglue/autoglue" { + version = "0.0.1" + constraints = "0.0.1" + hashes = [ + "h1:XW1zYWB6NTuE7jgJwWAkZeBBhL3Me36KE4Puy6lN6+o=", + ] +} + +provider "registry.opentofu.org/hashicorp/http" { + version = "3.5.0" + constraints = ">= 3.4.0" + hashes = [ + "h1:eClUBisXme48lqiUl3U2+H2a2mzDawS9biqfkd9synw=", + "zh:0a2b33494eec6a91a183629cf217e073be063624c5d3f70870456ddb478308e9", + "zh:180f40124fa01b98b3d2f79128646b151818e09d6a1a9ca08e0b032a0b1e9cb1", + "zh:3e29e1de149dc10bf78620526c7cb8c62cd76087f5630dfaba0e93cda1f3aa7b", + "zh:4420950200cf86042ec940d0e2c9b7c89966bf556bf8038ba36217eae663bca5", + "zh:5d1f7d02109b2e2dca7ec626e5563ee765583792d0fd64081286f16f9433bd0d", + "zh:8500b138d338b1994c4206aa577b5c44e1d7260825babcf43245a7075bfa52a5", + "zh:b42165a6c4cfb22825938272d12b676e4a6946ac4e750f85df870c947685df2d", + "zh:b919bf3ee8e3b01051a0da3433b443a925e272893d3724ee8fc0f666ec7012c9", + "zh:d13b81ea6755cae785b3e11634936cdff2dc1ec009dc9610d8e3c7eb32f42e69", + "zh:f1c9d2eb1a6b618ae77ad86649679241bd8d6aacec06d0a68d86f748687f4eb3", + ] +} + +provider "registry.opentofu.org/hashicorp/local" { + version = "2.5.3" + constraints = ">= 2.5.1" + hashes = [ + "h1:31Clmfoe7hzkcdgwuhUuGuPGfeG2Ksk+YWcJgzBTN7M=", + "zh:32e1d4b0595cea6cda4ca256195c162772ddff25594ab4008731a2ec7be230bf", + "zh:48c390af0c87df994ec9796f04ec2582bcac581fb81ed6bb58e0671da1c17991", + "zh:4be7289c969218a57b40902e2f359914f8d35a7f97b439140cb711aa21e494bd", + "zh:4cf958e631e99ed6c8b522c9b22e1f1b568c0bdadb01dd002ca7dffb1c927764", + "zh:7a0132c0faca4c4c96aa70808effd6817e28712bf5a39881666ac377b4250acf", + "zh:7d60de08fac427fb045e4590d1b921b6778498eee9eb16f78c64d4c577bde096", + "zh:91003bee5981e99ec3925ce2f452a5f743827f9d0e131a86613549c1464796f0", + "zh:9fe2fe75977c8149e2515fb30c6cc6cfd57b225d4ce592c570d81a3831d7ffa3", + "zh:e210e6be54933ce93e03d0994e520ba289aa01b2c1f70e77afb8f2ee796b0fe3", + "zh:e8793e5f9422f2b31a804e51806595f335b827c9a38db18766960464566f21d5", + ] +} + +provider "registry.opentofu.org/hashicorp/null" { + version = "3.2.4" + hashes = [ + "h1:i+WKhUHL2REY5EGmiHjfUljJB8UKZ9QdhdM5uTeUhC4=", + "zh:1769783386610bed8bb1e861a119fe25058be41895e3996d9216dd6bb8a7aee3", + "zh:32c62a9387ad0b861b5262b41c5e9ed6e940eda729c2a0e58100e6629af27ddb", + "zh:339bf8c2f9733fce068eb6d5612701144c752425cebeafab36563a16be460fb2", + "zh:36731f23343aee12a7e078067a98644c0126714c4fe9ac930eecb0f2361788c4", + "zh:3d106c7e32a929e2843f732625a582e562ff09120021e510a51a6f5d01175b8d", + "zh:74bcb3567708171ad83b234b92c9d63ab441ef882b770b0210c2b14fdbe3b1b6", + "zh:90b55bdbffa35df9204282251059e62c178b0ac7035958b93a647839643c0072", + "zh:ae24c0e5adc692b8f94cb23a000f91a316070fdc19418578dcf2134ff57cf447", + "zh:b5c10d4ad860c4c21273203d1de6d2f0286845edf1c64319fa2362df526b5f58", + "zh:e05bbd88e82e1d6234988c85db62fd66f11502645838fff594a2ec25352ecd80", + ] +} diff --git a/terraform/envs/dev/.terraform/modules/modules.json b/terraform/envs/dev/.terraform/modules/modules.json new file mode 100644 index 0000000..8096847 --- /dev/null +++ b/terraform/envs/dev/.terraform/modules/modules.json @@ -0,0 +1 @@ +{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"ssh","Source":"../../modules/ssh-key","Dir":"../../modules/ssh-key"}]} \ No newline at end of file diff --git a/terraform/envs/dev/.terraform/providers/glueops/autoglue/autoglue/0.0.1/darwin_arm64 b/terraform/envs/dev/.terraform/providers/glueops/autoglue/autoglue/0.0.1/darwin_arm64 new file mode 120000 index 0000000..e01b400 --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/glueops/autoglue/autoglue/0.0.1/darwin_arm64 @@ -0,0 +1 @@ +/Users/dragon/.terraform.d/plugins/glueops/autoglue/autoglue/0.0.1/darwin_arm64 \ No newline at end of file diff --git a/terraform/envs/dev/.terraform/providers/glueops/autoglue/autoglue/0.0.1/darwin_arm64.lock b/terraform/envs/dev/.terraform/providers/glueops/autoglue/autoglue/0.0.1/darwin_arm64.lock new file mode 100644 index 0000000..e69de29 diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64.lock b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64.lock new file mode 100644 index 0000000..e69de29 diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/CHANGELOG.md b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/CHANGELOG.md new file mode 100644 index 0000000..b4c6f18 --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/CHANGELOG.md @@ -0,0 +1,178 @@ +## 3.5.0 (April 23, 2025) + +FEATURES: + +* Add mTLS support (client cert & key) to http datasource ([#211](https://github.com/hashicorp/terraform-provider-http/issues/211)) + +## 3.4.5 (September 10, 2024) + +NOTES: + +* all: This release introduces no functional changes. It does however include dependency updates which address upstream CVEs. ([#452](https://github.com/hashicorp/terraform-provider-http/issues/452)) + +## 3.4.4 (July 31, 2024) + +NOTES: + +* data-source/http: Previous versions of this provider ignored any `Host` headers specified in the `request_headers` attribute when setting the HTTP request. Any specified `Host` request header will now be set on the HTTP request. + +For example, in the following configuration: +```hcl +data "http" "example" { + url = "https://www.example.com" + request_headers = { + Host = "www.differentexample.com" + } +} +``` +The HTTP request URL host is still `www.example.com` but the HTTP request `Host` header will now be `www.differentexample.com` instead of `www.example.com`. + ([#440](https://github.com/hashicorp/terraform-provider-http/issues/440)) + +BUG FIXES: + +* data-source/http: Allow `Host` header in `request_headers` to be set on HTTP request ([#440](https://github.com/hashicorp/terraform-provider-http/issues/440)) + +## 3.4.3 (June 03, 2024) + +BUG FIXES: + +* data-source/http: Avoid potentially leaking URL-embedded basic authentication credentials in logs and error messages ([#429](https://github.com/hashicorp/terraform-provider-http/issues/429)) + +## 3.4.2 (February 29, 2024) + +NOTES: + +* data-source/http: Previously the HTTP request would unexpectedly always contain a body for all requests. Certain HTTP server implementations are sensitive to this data existing if it is not expected. Requests now only contain a request body if the `request_body` attribute is explicitly set. To exactly preserve the previous behavior, set `request_body = ""`. ([#388](https://github.com/hashicorp/terraform-provider-http/issues/388)) + +BUG FIXES: + +* data-source/http: Ensured HTTP request body is not sent unless configured ([#388](https://github.com/hashicorp/terraform-provider-http/issues/388)) + +## 3.4.1 (December 19, 2023) + +BUG FIXES: + +* data-source/http: Includes update to go-retryablehttp fixing preservation of request body on temporary redirects or re-established HTTP/2 connections ([#346](https://github.com/hashicorp/terraform-provider-http/issues/346)) + +## 3.4.0 (June 21, 2023) + +ENHANCEMENTS: + +* data-source/http: `response_body_base64` has been added and contains a standard base64 encoding of the response body ([#158](https://github.com/hashicorp/terraform-provider-http/issues/158)) +* data-source/http: Replaced issuing warning on the basis of possible non-text `Content-Type` with issuing warning if response body does not contain valid UTF-8. ([#158](https://github.com/hashicorp/terraform-provider-http/issues/158)) + +## 3.3.0 (April 25, 2023) + +NOTES: + +* This Go module has been updated to Go 1.19 per the [Go support policy](https://golang.org/doc/devel/release.html#policy). Any consumers building on earlier Go versions may experience errors. ([#245](https://github.com/hashicorp/terraform-provider-http/issues/245)) + +ENHANCEMENTS: + +* data-source/http: Added `retry` with nested `attempts`, `max_delay_ms` and `min_delay_ms` ([#151](https://github.com/hashicorp/terraform-provider-http/issues/151)) +* data-source/http: Added `request_timeout_ms` ([#151](https://github.com/hashicorp/terraform-provider-http/issues/151)) + +## 3.2.1 (November 7, 2022) + +BUG FIXES + +* data-source/http: Using DefaultTransport to reinstate previous behavior (e.g., ProxyFromEnvironment) ([#198](https://github.com/hashicorp/terraform-provider-http/pull/198)). + +## 3.2.0 (October 31, 2022) + +ENHANCEMENTS: + +* data-source/http: Added `ca_cert_pem` attribute which allows PEM encoded certificate(s) to be included in the set of root certificate authorities used when verifying server certificates ([#125](https://github.com/hashicorp/terraform-provider-http/pull/125)). +* data-source/http: Added `insecure` attribute to allow disabling the verification of a server's certificate chain and host name. Defaults to `false` ([#125](https://github.com/hashicorp/terraform-provider-http/pull/125)). + +## 3.1.0 (August 30, 2022) + +ENHANCEMENTS: + +* data-source/http: Allow optionally specifying HTTP request method and body ([#21](https://github.com/hashicorp/terraform-provider-http/issues/21)). + +## 3.0.1 (July 27, 2022) + +BUG FIXES + +* data-source/http: Reinstated previously deprecated and removed `body` attribute ([#166](https://github.com/hashicorp/terraform-provider-http/pull/166)). + + +## 3.0.0 (July 27, 2022) + +NOTES: + +* Provider has been re-written using the new [`terraform-plugin-framework`](https://www.terraform.io/plugin/framework) ([#177](https://github.com/hashicorp/terraform-provider-http/pull/142)). + +BREAKING CHANGES: + +* data-source/http: Response status code is not checked anymore. A new read-only attribute, `status_code`, has been added. It can be used either with + [precondition and postcondition](https://www.terraform.io/language/expressions/custom-conditions#preconditions-and-postconditions) checks (Terraform >= 1.2.0), or, for instance, + with [local-exec Provisioner](https://www.terraform.io/language/resources/provisioners/local-exec) ([114](https://github.com/hashicorp/terraform-provider-http/pull/114)). +* data-source/http: Deprecated `body` has been removed ([#137](https://github.com/hashicorp/terraform-provider-http/pull/137)). + +## 2.2.0 (June 02, 2022) + +ENHANCEMENTS: + +* data-source/http: `body` is now deprecated and has been superseded by `response_body`. `body` will be removed in the next major release ([#137](https://github.com/hashicorp/terraform-provider-http/pull/137)). + +NOTES: + +* "Uplift" aligned with Utility Providers Upgrade ([#135](https://github.com/hashicorp/terraform-provider-http/issues/135)). + +## 2.1.0 (February 19, 2021) + +Binary releases of this provider now include the darwin-arm64 platform. This version contains no further changes. + +## 2.0.0 (October 14, 2020) + +Binary releases of this provider now include the linux-arm64 platform. + +BREAKING CHANGES: + +* Upgrade to version 2 of the Terraform Plugin SDK, which drops support for Terraform 0.11. This provider will continue to work as expected for users of Terraform 0.11, which will not download the new version. ([#47](https://github.com/terraform-providers/terraform-provider-http/issues/47)) + +IMPROVEMENTS: + +* Relaxed error on non-text `Content-Type` headers to be a warning instead ([#50](https://github.com/terraform-providers/terraform-provider-http/issues/50)) + +BUG FIXES: + +* Modified some of the documentation to work a bit better in the registry ([#42](https://github.com/terraform-providers/terraform-provider-http/issues/42)) +* Allowed the `us-ascii` charset in addition to `utf-8` ([#43](https://github.com/terraform-providers/terraform-provider-http/issues/43)) + +## 1.2.0 (March 17, 2020) + +IMPROVEMENTS: + +* Switch to v1.7.0 of the standalone plugin SDK ([#35](https://github.com/terraform-providers/terraform-provider-http/issues/35)) +* Added response_headers to datasource ([#31](https://github.com/terraform-providers/terraform-provider-http/issues/31)) + +BUG FIXES: + +* Fix request error message to include the `err` and not just url ([#26](https://github.com/terraform-providers/terraform-provider-http/issues/26)) + +## 1.1.1 (May 01, 2019) + +* This release includes an upgrade to the Terraform SDK, in an effort to help align with what other providers are releasing with, as we lead up to Core v0.12. It should have no noticeable impact on the provider. + +## 1.1.0 (April 18, 2019) + +IMPROVEMENTS: + +* The provider is now compatible with Terraform v0.12, while retaining compatibility with prior versions. + +## 1.0.1 (January 03, 2018) + +* Allow `charset` argument on `Content-Type` ([#5](https://github.com/terraform-providers/terraform-provider-http/issues/5)) + +## 1.0.0 (September 14, 2017) + +* add content type for ADFS FederationMetadata.xml ([#4](https://github.com/terraform-providers/terraform-provider-http/issues/4)) + +## 0.1.0 (June 20, 2017) + +NOTES: + +* Same functionality as that of Terraform 0.9.8. Repacked as part of [Provider Splitout](https://www.hashicorp.com/blog/upcoming-provider-changes-in-terraform-0-10/) diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/LICENSE b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/LICENSE new file mode 100644 index 0000000..b9ac071 --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/LICENSE @@ -0,0 +1,375 @@ +Copyright (c) 2017 HashiCorp, Inc. + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/README.md b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/README.md new file mode 100644 index 0000000..dca5b7b --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/README.md @@ -0,0 +1,113 @@ +# Terraform Provider: HTTP + +The HTTP provider interacts with generic HTTP servers. +It provides a data source that issues an HTTP request exposing the response headers and body +for use within a Terraform deployment. + +## Documentation, questions and discussions + +Official documentation on how to use this provider can be found on the +[Terraform Registry](https://registry.terraform.io/providers/hashicorp/http/latest/docs). +In case of specific questions or discussions, please use the +HashiCorp [Terraform Providers Discuss forums](https://discuss.hashicorp.com/c/terraform-providers/31), +in accordance with HashiCorp [Community Guidelines](https://www.hashicorp.com/community-guidelines). + +We also provide: + +* [Support](.github/SUPPORT.md) page for help when using the provider +* [Contributing](.github/CONTRIBUTING.md) guidelines in case you want to help this project +* [Design](DESIGN.md) documentation to understand the scope and maintenance decisions + +The remainder of this document will focus on the development aspects of the provider. + +## Compatibility + +Compatibility table between this provider, +the [Terraform Plugin Protocol](https://www.terraform.io/plugin/how-terraform-works#terraform-plugin-protocol) +version it implements, and Terraform: + +| HTTP Provider | Terraform Plugin Protocol | Terraform | +|:----------------------:|:-------------------------:|:---------:| +| `>= 2.x` | `5` | `>= 0.12` | +| `>= 1.1.x`, `<= 1.2.x` | `4`, `5` | `>= 0.11` | +| `<= 1.0.x` | `4` | `<= 0.11` | + +## Requirements + +* [Terraform](https://www.terraform.io/downloads) +* [Go](https://go.dev/doc/install) (1.23) +* [GNU Make](https://www.gnu.org/software/make/) +* [golangci-lint](https://golangci-lint.run/welcome/install/#local-installation) (optional) + +## Development + +### Building + +1. `git clone` this repository and `cd` into its directory +2. `make` will trigger the Golang build + +The provided `GNUmakefile` defines additional commands generally useful during development, +like for running tests, generating documentation, code formatting and linting. +Taking a look at it's content is recommended. + +### Testing + +In order to test the provider, you can run + +* `make test` to run provider tests +* `make testacc` to run provider acceptance tests + +It's important to note that acceptance tests (`testacc`) will actually spawn +`terraform` and the provider. Read more about they work on the +[official page](https://www.terraform.io/plugin/sdkv2/testing/acceptance-tests). + +### Generating documentation + +This provider uses [terraform-plugin-docs](https://github.com/hashicorp/terraform-plugin-docs/) +to generate documentation and store it in the `docs/` directory. +Once a release is cut, the Terraform Registry will download the documentation from `docs/` +and associate it with the release version. Read more about how this works on the +[official page](https://www.terraform.io/registry/providers/docs). + +Use `make generate` to ensure the documentation is regenerated with any changes. + +### Using a development build + +If [running tests and acceptance tests](#testing) isn't enough, it's possible to set up a local terraform configuration +to use a development builds of the provider. This can be achieved by leveraging the Terraform CLI +[configuration file development overrides](https://www.terraform.io/cli/config/config-file#development-overrides-for-provider-developers). + +First, use `make install` to place a fresh development build of the provider in your +[`${GOBIN}`](https://pkg.go.dev/cmd/go#hdr-Compile_and_install_packages_and_dependencies) +(defaults to `${GOPATH}/bin` or `${HOME}/go/bin` if `${GOPATH}` is not set). Repeat +this every time you make changes to the provider locally. + +Then, setup your environment following [these instructions](https://www.terraform.io/plugin/debugging#terraform-cli-development-overrides) +to make your local terraform use your local build. + +### Testing GitHub Actions + +This project uses [GitHub Actions](https://docs.github.com/en/actions/automating-builds-and-tests) to realize its CI. + +Sometimes it might be helpful to locally reproduce the behaviour of those actions, +and for this we use [act](https://github.com/nektos/act). Once installed, you can _simulate_ the actions executed +when opening a PR with: + +```shell +# List of workflows for the 'pull_request' action +$ act -l pull_request + +# Execute the workflows associated with the `pull_request' action +$ act pull_request +``` + +## Releasing + +The release process is automated via GitHub Actions, and it's defined in the Workflow +[release.yml](./.github/workflows/release.yml). + +Each release is cut by pushing a [semantically versioned](https://semver.org/) tag to the default branch. + +## License + +[Mozilla Public License v2.0](./LICENSE) diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/terraform-provider-http b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/terraform-provider-http new file mode 100755 index 0000000..1a6f2af Binary files /dev/null and b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/http/3.5.0/darwin_arm64/terraform-provider-http differ diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64.lock b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64.lock new file mode 100644 index 0000000..e69de29 diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/CHANGELOG.md b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/CHANGELOG.md new file mode 100644 index 0000000..c2ee5da --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/CHANGELOG.md @@ -0,0 +1,185 @@ +## 2.5.3 (May 08, 2025) + +NOTES: + +* Update dependencies ([#404](https://github.com/hashicorp/terraform-provider-local/issues/404)) + +## 2.5.3-alpha1 (April 24, 2025) + +NOTES: + +* This release is being used to test new build and release actions. ([#405](https://github.com/hashicorp/terraform-provider-local/issues/405)) + +## 2.5.2 (September 11, 2024) + +NOTES: + +* all: This release introduces no functional changes. It does however include dependency updates which address upstream CVEs. ([#348](https://github.com/hashicorp/terraform-provider-local/issues/348)) + +## 2.5.1 (March 11, 2024) + +NOTES: + +* No functional changes from v2.5.0. Minor documentation fixes. ([#303](https://github.com/hashicorp/terraform-provider-local/issues/303)) + +## 2.5.0 (March 11, 2024) + +FEATURES: + +* functions/direxists: Added a new `direxists` function that checks for the existence of a directory, similar to the built-in `fileexists` function. ([#285](https://github.com/hashicorp/terraform-provider-local/issues/285)) + +## 2.4.1 (December 12, 2023) + +NOTES: + +* This release introduces no functional changes. It does however include dependency updates which address upstream CVEs. ([#273](https://github.com/hashicorp/terraform-provider-local/issues/273)) + +## 2.4.0 (March 08, 2023) + +NOTES: + +* This Go module has been updated to Go 1.19 per the [Go support policy](https://golang.org/doc/devel/release.html#policy). Any consumers building on earlier Go versions may experience errors. ([#184](https://github.com/hashicorp/terraform-provider-local/issues/184)) + +FEATURES: + +* resource/local_file: added support for `MD5`, `SHA1`, `SHA256`, and `SHA512` checksum outputs. ([#142](https://github.com/hashicorp/terraform-provider-local/issues/142)) +* resource/local_sensitive_file: added support for `MD5`, `SHA1`, `SHA256`, and `SHA512` checksum outputs. ([#142](https://github.com/hashicorp/terraform-provider-local/issues/142)) +* data-source/local_file: added support for `MD5`, `SHA1`, `SHA256`, and `SHA512` checksum outputs. ([#142](https://github.com/hashicorp/terraform-provider-local/issues/142)) +* data-source/local_sensitive-file: added support for `MD5`, `SHA1`, `SHA256`, and `SHA512` checksum outputs. ([#142](https://github.com/hashicorp/terraform-provider-local/issues/142)) + +## 2.3.0 (January 11, 2023) + +NOTES: + +* provider: Rewritten to use the [`terraform-plugin-framework`](https://www.terraform.io/plugin/framework) ([#155](https://github.com/hashicorp/terraform-provider-local/issues/155)) + +## 2.2.3 (May 18, 2022) + +NOTES: + +* resource/local_file: Update docs to prevent confusion that exactly one of the arguments `content`, + `sensitive_content`, `content_base64`, and `source` needs to be specified ([#123](https://github.com/hashicorp/terraform-provider-local/pull/123)). + +* resource/local_sensitive_file: Update docs to prevent confusion that exactly one of the arguments `content`, + `content_base64`, and `source` needs to be specified ([#123](https://github.com/hashicorp/terraform-provider-local/pull/123)). + +* No functional changes from 2.2.2. + +## 2.2.2 (March 11, 2022) + +NOTES: + +* resource/local_sensitive_file: Fixed typo in documentation (default permission is `"0700"`, not `"0777"`). +* No functional changes from 2.2.1. + +## 2.2.1 (March 10, 2022) + +NOTES: + +* This release is a republishing of the 2.2.0 release to fix release asset checksum errors. It is identical otherwise. + +## 2.2.0 (March 10, 2022) + +NOTES: + +* resource/local_file: Argument `sensitive_content` is `Deprecated`. For creating or accessing files containing sensitive data, + please use the new resource and data source `local_sensitive_file`. + Both are identical to their `local_file` counterparts, but `content` and `content_base64` attributes are marked as _sensitive_. + +FEATURES: + +* **New Data Source:** `local_sensitive_file` ([#101](https://github.com/hashicorp/terraform-provider-local/pull/101) and [#106](https://github.com/hashicorp/terraform-provider-local/pull/106)) +* **New Resource:** `local_sensitive_file` ([#106](https://github.com/hashicorp/terraform-provider-local/pull/106)) + +## 2.1.0 (February 19, 2021) + +NOTES: + +* Binary releases of this provider now include the` darwin-arm64` platform. +* This version contains no further changes. + +## 2.0.0 (October 14, 2020) + +NOTES: + +* Binary releases of this provider now include the `linux-arm64` platform. + +BREAKING CHANGES: + +* Upgrade to version 2 of the Terraform Plugin SDK, which drops support for Terraform 0.11. + This provider will continue to work as expected for users of Terraform 0.11, which will not download the new version. + ([#42](https://github.com/terraform-providers/terraform-provider-local/issues/42)) + +FEATURES: + +* resource/local_file: Added `source` attribute as alternative way to provide content + for the `local_file` resource. + ([#44](https://github.com/terraform-providers/terraform-provider-local/issues/44)) + +## 1.4.0 (September 30, 2019) + +NOTES: + +* The provider has switched to the standalone TF SDK, there should be no noticeable impact on compatibility. + ([#32](https://github.com/terraform-providers/terraform-provider-local/issues/32)) + +FEATURES: + +* resource/local_file: Added support for configurable permissions + ([#30](https://github.com/terraform-providers/terraform-provider-local/issues/30)) + +## 1.3.0 (June 26, 2019) + +FEATURES: + +* resource/local_file: Added support for base64 encoded content + ([#29](https://github.com/terraform-providers/terraform-provider-local/issues/29)) +* data-source/local_file: Added support for base64 encoded content + ([#29](https://github.com/terraform-providers/terraform-provider-local/issues/29)) + +## 1.2.2 (May 01, 2019) + +NOTES: + +* This releases includes another Terraform SDK upgrade intended to align with that being used for other providers + as we prepare for the Core `v0.12.0` release. It should have no significant changes in behavior for this provider. + +## 1.2.1 (April 11, 2019) + +NOTES: + +* This releases includes only a Terraform SDK upgrade intended to align with that being used for other providers + as we prepare for the Core `v0.12.0` release. It should have no significant changes in behavior for this provider. + +## 1.2.0 (March 20, 2019) + +FEATURES: + +* The provider is now compatible with Terraform v0.12, while retaining compatibility with prior versions. +* resource/local_file: added optional `sensitive_content` attribute, which can be used instead of `content` + in situations where the content contains sensitive information that should not be displayed in a rendered diff. + ([#9](https://github.com/terraform-providers/terraform-provider-local/issues/9)) + +## 1.1.0 (January 04, 2018) + +FEATURES: + +* data-source/local_file: Added for reading files in a way that participates in Terraform's dependency graph, + which allows reading of files that are created dynamically during `terraform apply`. + ([#6](https://github.com/terraform-providers/terraform-provider-local/issues/6)) + +## 1.0.0 (September 15, 2017) + +NOTES: + +* No changes from 0.1.0; just adjusting to + [the new version numbering scheme](https://www.hashicorp.com/blog/hashicorp-terraform-provider-versioning/). + +## 0.1.0 (June 21, 2017) + +NOTES: + +* Same functionality as that of Terraform 0.9.8. + Repacked as part of [Provider Splitout](https://www.hashicorp.com/blog/upcoming-provider-changes-in-terraform-0-10/) + + diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/LICENSE b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/LICENSE new file mode 100644 index 0000000..b9ac071 --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/LICENSE @@ -0,0 +1,375 @@ +Copyright (c) 2017 HashiCorp, Inc. + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/README.md b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/README.md new file mode 100644 index 0000000..a99aa67 --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/README.md @@ -0,0 +1,125 @@ +# Terraform Provider: Local + +The Local provider is used to manage local resources, such as files. + + +**Note** Terraform primarily deals with remote resources which are able +to outlive a single Terraform run, and so local resources can sometimes violate +its assumptions. The resources here are best used with care, since depending +on local state can make it hard to apply the same Terraform configuration on +many different local systems where the local resources may not be universally +available. See specific notes in each resource for more information. + + +## Documentation, questions and discussions + +Official documentation on how to use this provider can be found on the +[Terraform Registry](https://registry.terraform.io/providers/hashicorp/local/latest/docs). +In case of specific questions or discussions, please use the +HashiCorp [Terraform Providers Discuss forums](https://discuss.hashicorp.com/c/terraform-providers/31), +in accordance with HashiCorp [Community Guidelines](https://www.hashicorp.com/community-guidelines). + +We also provide: + +* [Support](.github/SUPPORT.md) page for help when using the provider +* [Contributing](.github/CONTRIBUTING.md) guidelines in case you want to help this project + +The remainder of this document will focus on the development aspects of the provider. + +## Compatibility + +Compatibility table between this provider, the [Terraform Plugin Protocol](https://www.terraform.io/plugin/how-terraform-works#terraform-plugin-protocol) +version it implements, and Terraform: + +| TLS Provider | Terraform Plugin Protocol | Terraform | +|:------------:|:-------------------------:|:---------:| +| `>= 2.x` | `5` | `>= 0.12` | +| `>= 1.1.x` | `4` and `5` | `<= 0.12` | +| `>= 0.x` | `4` | `<= 0.11` | + +Details can be found querying the [Registry API](https://www.terraform.io/internals/provider-registry-protocol#list-available-versions) +that return all the details about which version are currently available for a particular provider. +[Here](https://registry.terraform.io/v1/providers/hashicorp/local/versions) are the details for Local (JSON response). + +## Requirements + +* [Terraform](https://www.terraform.io/downloads) +* [Go](https://go.dev/doc/install) (1.23) +* [GNU Make](https://www.gnu.org/software/make/) +* [golangci-lint](https://golangci-lint.run/usage/install/#local-installation) (optional) + +## Development + +### Building + +1. `git clone` this repository and `cd` into its directory +2. `make` will trigger the Golang build + +The provided `GNUmakefile` defines additional commands generally useful during development, +like for running tests, generating documentation, code formatting and linting. +Taking a look at it's content is recommended. + +### Testing + +In order to test the provider, you can run + +* `make test` to run provider tests +* `make testacc` to run provider acceptance tests + +It's important to note that acceptance tests (`testacc`) will actually spawn +`terraform` and the provider. Read more about they work on the +[official page](https://www.terraform.io/plugin/sdkv2/testing/acceptance-tests). + +### Generating documentation + +This provider uses [terraform-plugin-docs](https://github.com/hashicorp/terraform-plugin-docs/) +to generate documentation and store it in the `docs/` directory. +Once a release is cut, the Terraform Registry will download the documentation from `docs/` +and associate it with the release version. Read more about how this works on the +[official page](https://www.terraform.io/registry/providers/docs). + +Use `make generate` to ensure the documentation is regenerated with any changes. + +### Using a development build + +If [running tests and acceptance tests](#testing) isn't enough, it's possible to set up a local terraform configuration +to use a development builds of the provider. This can be achieved by leveraging the Terraform CLI +[configuration file development overrides](https://www.terraform.io/cli/config/config-file#development-overrides-for-provider-developers). + +First, use `make install` to place a fresh development build of the provider in your +[`${GOBIN}`](https://pkg.go.dev/cmd/go#hdr-Compile_and_install_packages_and_dependencies) +(defaults to `${GOPATH}/bin` or `${HOME}/go/bin` if `${GOPATH}` is not set). Repeat +this every time you make changes to the provider locally. + +Then, setup your environment following [these instructions](https://www.terraform.io/plugin/debugging#terraform-cli-development-overrides) +to make your local terraform use your local build. + +### Testing GitHub Actions + +This project uses [GitHub Actions](https://docs.github.com/en/actions/automating-builds-and-tests) to realize its CI. + +Sometimes it might be helpful to locally reproduce the behaviour of those actions, +and for this we use [act](https://github.com/nektos/act). Once installed, you can _simulate_ the actions executed +when opening a PR with: + +```shell +# List of workflows for the 'pull_request' action +$ act -l pull_request + +# Execute the workflows associated with the `pull_request' action +$ act pull_request +``` + +## Releasing + +The releasable builds are generated from the [build GH workflow](./.github/workflows/build.yml) and the release/promotion process +is completed via internal HashiCorp deployment tooling. Prior to release, the changelog should be updated in `main` with +the changie tool, example: + +```sh +changie batch 2.5.3 && changie merge +``` + +## License + +[Mozilla Public License v2.0](./LICENSE) diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/terraform-provider-local b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/terraform-provider-local new file mode 100755 index 0000000..82491ed Binary files /dev/null and b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/local/2.5.3/darwin_arm64/terraform-provider-local differ diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64.lock b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64.lock new file mode 100644 index 0000000..e69de29 diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/CHANGELOG.md b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/CHANGELOG.md new file mode 100644 index 0000000..adf9fac --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/CHANGELOG.md @@ -0,0 +1,92 @@ +## 3.2.4 (April 21, 2025) + +NOTES: + +* Dependency updates ([#421](https://github.com/hashicorp/terraform-provider-null/issues/421)) + +## 3.2.4-alpha1 (February 19, 2025) + +NOTES: + +* all: This release is being used to test new build and release actions. + +## 3.2.4-alpha.2 (March 27, 2025) + +NOTES: + +* all: This release is being used to test new build and release actions. + +## 3.2.3 (September 11, 2024) + +NOTES: + +* all: This release introduces no functional changes. It does however include dependency updates which address upstream CVEs. ([#366](https://github.com/hashicorp/terraform-provider-null/issues/366)) + +## 3.2.2 (November 20, 2023) + +NOTES: + +* This release introduces no functional changes. It does however include dependency updates which address upstream CVEs. ([#242](https://github.com/hashicorp/terraform-provider-null/issues/242)) + +## 3.2.1 (November 17, 2022) + +BUG FIXES: + +* provider: Fix random number generation for `id` attributes ([#160](https://github.com/hashicorp/terraform-provider-null/pull/160)) + +## 3.2.0 (October 25, 2022) + +NOTES: + +* Provider: Rewritten to use the new [`terraform-plugin-framework`](https://www.terraform.io/plugin/framework) ([#150](https://github.com/hashicorp/terraform-provider-null/pull/150)) + +## 3.1.1 (March 16, 2022) + +NOTES: + +* Updated [terraform-plugin-docs](https://github.com/hashicorp/terraform-plugin-docs) to `v0.7.0`: + this improves generated documentation, with attributes now correctly formatted as `code` + and provided with anchors. +* Functionally identical to the previous 3.1.0 release. + +## 3.1.0 (February 19, 2021) + +Binary releases of this provider now include the darwin-arm64 platform. This version contains no further changes. + +## 3.0.0 (October 08, 2020) + +Binary releases of this provider now include the linux-arm64 platform. + +BREAKING CHANGES: + +* Upgrade to version 2 of the Terraform Plugin SDK, which drops support for Terraform 0.11. This provider will continue to work as expected for users of Terraform 0.11, which will not download the new version. ([#47](https://github.com/terraform-providers/terraform-provider-null/issues/47)) + +## 2.1.2 (April 30, 2019) + +* This releases includes another Terraform SDK upgrade intended to align with that being used for other providers as we prepare for the Core v0.12.0 release. It should have no significant changes in behavior for this provider. + +## 2.1.1 (April 11, 2019) + +* This releases includes only a Terraform SDK upgrade intended to align with that being used for other providers as we prepare for the Core v0.12.0 release. It should have no significant changes in behavior for this provider. + +## 2.1.0 (February 27, 2019) + +IMPROVEMENTS: + +* The previous release contains an SDK incompatible with TF 0.12. Fortunately 0.12 was not released yet so upgrading the vendored sdk makes this release compatible with 0.12. + +## 2.0.0 (January 18, 2019) + +IMPROVEMENTS: + +* The provider is now compatible with Terraform v0.12, while retaining compatibility with prior versions. + +## 1.0.0 (September 26, 2017) + +* No changes from 0.1.0; just adjusting to [the new version numbering scheme](https://www.hashicorp.com/blog/hashicorp-terraform-provider-versioning/). + +## 0.1.0 (June 21, 2017) + +NOTES: + +* Same functionality as that of Terraform 0.9.8. Repacked as part of [Provider Splitout](https://www.hashicorp.com/blog/upcoming-provider-changes-in-terraform-0-10/) diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/LICENSE b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/LICENSE new file mode 100644 index 0000000..b9ac071 --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/LICENSE @@ -0,0 +1,375 @@ +Copyright (c) 2017 HashiCorp, Inc. + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/README.md b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/README.md new file mode 100644 index 0000000..8c0d19b --- /dev/null +++ b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/README.md @@ -0,0 +1,113 @@ +# Terraform Provider: Null + +The Null provider is a rather-unusual provider that has constructs that intentionally do nothing. This may sound strange, and indeed these constructs do not need to be used in most cases, but they can be useful in various situations to help orchestrate tricky behavior or work around limitations. + +## Requirements + +* [Terraform](https://www.terraform.io/downloads) +* [Go](https://go.dev/doc/install) (1.23) +* [GNU Make](https://www.gnu.org/software/make/) +* [golangci-lint](https://golangci-lint.run/usage/install/#local-installation) (optional) + +## Documentation, questions and discussions +Official documentation on how to use this provider can be found on the +[Terraform Registry](https://registry.terraform.io/providers/hashicorp/null/latest/docs). +In case of specific questions or discussions, please use the +HashiCorp [Terraform Providers Discuss forums](https://discuss.hashicorp.com/c/terraform-providers/31), +in accordance with HashiCorp [Community Guidelines](https://www.hashicorp.com/community-guidelines). + +We also provide: + +* [Support](.github/SUPPORT.md) page for help when using the provider +* [Contributing](.github/CONTRIBUTING.md) guidelines in case you want to help this project + +## Compatibility + +Compatibility table between this provider, the [Terraform Plugin Protocol](https://www.terraform.io/plugin/how-terraform-works#terraform-plugin-protocol) +version it implements, and Terraform: + +| Null Provider | Terraform Plugin Protocol | Terraform | +|:-------------:|:-------------------------:|:---------:| +| `>= 3.0.x` | `5` | `>= 0.12` | +| `>= 2.1.x` | `4` and `5` | `>= 0.12` | +| `>= 2.x.x` | `4` | `<= 0.12` | +| `>= 1.x.x` | `4` | `<= 0.12` | +| `>= 0.1.x` | `4` | `<= 0.12` | + +Details can be found querying the [Registry API](https://www.terraform.io/internals/provider-registry-protocol#list-available-versions) +that return all the details about which version are currently available for a particular provider. +[Here](https://registry.terraform.io/v1/providers/hashicorp/null/versions) are the details for Time (JSON response). + + +## Development + +### Building + +1. `git clone` this repository and `cd` into its directory +2. `make` will trigger the Golang build + +The provided `GNUmakefile` defines additional commands generally useful during development, +like for running tests, generating documentation, code formatting and linting. +Taking a look at it's content is recommended. + +### Testing + +In order to test the provider, you can run + +* `make test` to run provider tests +* `make testacc` to run provider acceptance tests + +It's important to note that acceptance tests (`testacc`) will actually spawn +`terraform` and the provider. Read more about they work on the +[official page](https://www.terraform.io/plugin/sdkv2/testing/acceptance-tests). + +### Generating documentation + +This provider uses [terraform-plugin-docs](https://github.com/hashicorp/terraform-plugin-docs/) +to generate documentation and store it in the `docs/` directory. +Once a release is cut, the Terraform Registry will download the documentation from `docs/` +and associate it with the release version. Read more about how this works on the +[official page](https://www.terraform.io/registry/providers/docs). + +Use `make generate` to ensure the documentation is regenerated with any changes. + +### Using a development build + +If [running tests and acceptance tests](#testing) isn't enough, it's possible to set up a local terraform configuration +to use a development builds of the provider. This can be achieved by leveraging the Terraform CLI +[configuration file development overrides](https://www.terraform.io/cli/config/config-file#development-overrides-for-provider-developers). + +First, use `make install` to place a fresh development build of the provider in your +[`${GOBIN}`](https://pkg.go.dev/cmd/go#hdr-Compile_and_install_packages_and_dependencies) +(defaults to `${GOPATH}/bin` or `${HOME}/go/bin` if `${GOPATH}` is not set). Repeat +this every time you make changes to the provider locally. + +Then, setup your environment following [these instructions](https://www.terraform.io/plugin/debugging#terraform-cli-development-overrides) +to make your local terraform use your local build. + +### Testing GitHub Actions + +This project uses [GitHub Actions](https://docs.github.com/en/actions/automating-builds-and-tests) to realize its CI. + +Sometimes it might be helpful to locally reproduce the behaviour of those actions, +and for this we use [act](https://github.com/nektos/act). Once installed, you can _simulate_ the actions executed +when opening a PR with: + +```shell +# List of workflows for the 'pull_request' action +$ act -l pull_request + +# Execute the workflows associated with the `pull_request' action +$ act pull_request +``` + +## Releasing + +The release process is automated via GitHub Actions, and it's defined in the Workflow +[release.yml](./.github/workflows/release.yml). + +Each release is cut by pushing a [semantically versioned](https://semver.org/) tag to the default branch. + +## License + +[Mozilla Public License v2.0](./LICENSE) \ No newline at end of file diff --git a/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/terraform-provider-null b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/terraform-provider-null new file mode 100755 index 0000000..3bc0178 Binary files /dev/null and b/terraform/envs/dev/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.4/darwin_arm64/terraform-provider-null differ diff --git a/terraform/envs/dev/main.tf b/terraform/envs/dev/main.tf new file mode 100644 index 0000000..07c62a1 --- /dev/null +++ b/terraform/envs/dev/main.tf @@ -0,0 +1,29 @@ +# Use the module N times with for_each +module "ssh" { + source = "../../modules/ssh-key" + for_each = var.ssh_keys + + # Pass through inputs + addr = var.addr # used by HTTP download URL + name = each.value.name + comment = each.value.comment + type = each.value.type + bits = try(each.value.bits, null) + enable_download = try(each.value.enable_download, true) + download_part = try(each.value.download_part, "both") + download_dir = try(each.value.download_dir, "out/${each.key}") + + org_key = var.org_key + org_secret = var.org_secret +} + +# Example: aggregate outputs by key +output "ssh_ids" { + value = { for k, m in module.ssh : k => m.id } +} +output "ssh_public_keys" { + value = { for k, m in module.ssh : k => m.public_key } +} +output "ssh_written_files" { + value = { for k, m in module.ssh : k => m.written_files } +} diff --git a/terraform/envs/dev/providers.tf b/terraform/envs/dev/providers.tf new file mode 100644 index 0000000..769acf4 --- /dev/null +++ b/terraform/envs/dev/providers.tf @@ -0,0 +1,5 @@ +provider "autoglue" { + addr = var.addr + org_key = var.org_key + org_secret= var.org_secret +} \ No newline at end of file diff --git a/terraform/envs/dev/terraform.tfstate b/terraform/envs/dev/terraform.tfstate new file mode 100644 index 0000000..4d2eda5 --- /dev/null +++ b/terraform/envs/dev/terraform.tfstate @@ -0,0 +1 @@ +{"version":4,"terraform_version":"1.10.6","serial":2,"lineage":"6ea5f588-9a03-6b57-9ea8-06e8e7fc2461","outputs":{},"resources":[],"check_results":[{"object_kind":"resource","config_addr":"module.ssh.local_sensitive_file.zip","status":"unknown","objects":null}]} diff --git a/terraform/envs/dev/terraform.tfstate.backup b/terraform/envs/dev/terraform.tfstate.backup new file mode 100644 index 0000000..c221858 --- /dev/null +++ b/terraform/envs/dev/terraform.tfstate.backup @@ -0,0 +1 @@ +{"version":4,"terraform_version":"1.10.6","serial":1,"lineage":"6ea5f588-9a03-6b57-9ea8-06e8e7fc2461","outputs":{"ssh_ids":{"value":{"key1":"8e9a0707-02ec-483d-abb7-1c45d199c116","key2":"44803472-4c2e-433f-a05d-38b1bbfb1e24"},"type":["object",{"key1":"string","key2":"string"}]},"ssh_public_keys":{"value":{"key1":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDN7NbCCLUqyhUFIpEznbNhvRg2mHMskfu/iV74kS7mvhc/v03CPheJad1rAiu50+5Ow8+ZKyrjmimw9Ph5Jp8vDlHNu8xio8AkDmvjiq0kGteGZETr368z2ZoDYBDpk1wIdvF8XxBZysKiPMjt/x/pg4xWPaJxZ+Nk2+lJt+l604AO7Bcs8vLChRn9GpaRoWz9KO2v0R9YNX8JUsifwJ6celXYXI1/IwCjpChNUyC/XdeU8hpgM7Au/f4h3L/slu8eTYSB+VsoIwITDIYiebsARj+949dnoM/SCoCOy6ljv35PnfKlD8f+nz8Jro5IkFc42HWk9P4CnDkLsXsqCpKo4VoufWI14VJaT39Pwe7gqdTnsr/vGHftJuUoCK7kEZFBQP4GrJjcvoWChJ72DEIKCcF3+Q4mp80sE9LsZAhmYyDbxueD7wQ+IA/edekU8kv6H2RFwNe8CQx0M3hSqEtACBNl72ogse691bxDmhyG7aaSOD0H9BtlZ4wR5c0OBq55BxRaKG1bok/8tFkctj+6uhbHdBUBHxu2nW5wkZdT75kEEZSCLEm7HHfiWVmZcc7uOAAVwinF+U7eT0ndjbYvz4yKV5+anz8mnMiWTV1y2PdJUGiGrCwQ9bQva4VeZT7HcxCMwqTwchvqjN+exHjjTUtKo9UkOXE0zwcA8nz+Gw== deploy1@autoglue","key2":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGSLRxWdx6Z4aNuoJ7GGmvjilsqbL7clLVdrXanYQryr deploy2@autoglue"},"type":["object",{"key1":"string","key2":"string"}]},"ssh_written_files":{"value":{"key1":["out/key1/id_rsa_8e9a0707-02ec-483d-abb7-1c45d199c116.zip"],"key2":["out/key2/id_rsa_44803472-4c2e-433f-a05d-38b1bbfb1e24.zip"]},"type":["object",{"key1":["list","string"],"key2":["list","string"]}]}},"resources":[{"module":"module.ssh[\"key1\"]","mode":"data","type":"http","name":"download","provider":"provider[\"registry.opentofu.org/hashicorp/http\"]","instances":[{"index_key":0,"schema_version":0,"attributes":{"body":"{\"id\":\"8e9a0707-02ec-483d-abb7-1c45d199c116\",\"name\":\"CI deploy key 1\",\"fingerprint\":\"SHA256:VxjPg+mm+WKYizRKUHSxB95D5lo961XcYZrnpQerTm0\",\"zip_base64\":\"UEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wZW1sl7USrAoCBXO+4ubUFm7BBrgzyKAZMLi7fP3Wu5u+k56sq5P+zz/jRFm1/rge+8d21YD9in90Mf77AKaqajqrciyr82wlsm/xhlfVIPo2BZynuyaBvnEGx9Zcv4amUCfeF6AmHsSKRzbFWMDV4lETjr/0UtfjZx/fzbYHb1twYpo3+4sXXloaF+G+2WnGi81qLLHi+LJr3BrVgysCJAOeJjOkLMo6ZGLlvJLdpUQ7Yb7yU/uqVEmXZPwxgxZt8rBsE+ucvayci/3DCscVAYZtPNfkJ5C7hF0qbZDX7isjlqEQQHxgqCPNF6MyB6j0WOVjshPpTN/ArE4Ei3pbTYFY+FzGiYHq74EoLTuVDhWrss903uTF65HVcaBYMYbOwo4SUrDhamHb7ZhjigG/BPYAswMp0ExDfEp+PI2LPlaNzPYXZOeL4CmJ0qvFWz5SaoxIYxWSF3YM9KWVA9dHn6B0CKDuGqO8rNfZ5iA42XV8AeSWJ8YMUqomr2Cqm+erkftB3UdbSsvgbI+SHTUZzAqlsxGoQFq0G9bGxmiWbM0Aa6ZzcyE62c78CRbuL7XhsNU3KZhFNZTj/IW0Q0x5faBD11YMwEFOloSFKRaRJVTpUTi5Hzb1HpKaDRluohgxdKxTeGNOwLp0ts/IkWty5INgwnGyD1TNrR33jeF9nwyR8qHaipVydb7L/oN1jIbFKGrQoNn0RTnMNKTNr9p3yC/fW8wLuAmol2sT7RA20EOKBh+8MdNpTb2jFTUjp7ccNxfHYcTwFjvQhP62TFphbY2G6o1nL5EFWOcfhdnk6aHsG5ytz543aWgDovYPIZ4wP9mN4yVhvWGHSfM0FxkC6Mkw2xpOfikxYLlIhxrxxb3xRJr04PeNHHslU8utkYLgQ+haVwiY6nZxTkZSTwgpKbTfb19wRtsEBkAcFxaYSMNWn3xi99wkWhO1WTdadadUekVkRL86iRFGTT9VXSn7lSa3hFWKwxlFgjXQ4cYk92AuBc5Z2RLNr/kRU1B+tWbmlnmal7B8wodkvlPMeJyPICd+EMMjbvkh47IKjDy8J8p4OGk+4LyTdltZHofivji86SR7yXznObEinfrKWKh3LtEVRxoUGYph444CA5rSWGWVHA2Pvs+7i6B8bsOJ1UwtKiAkOAOh2MWiK2TlnmIxU10HK0NhqreymQVvwoDd0jXP/wSaqTGqVPoDT/Aood+7Y10hcWcDOYn7S6Vah7ahpX0o7DDgz865QevAJaYACSm12Y4HDwNTKdFRi7wa00ry1rvqYldtCKEjm/i5OE8R4P04itNJ0MNOZjIa12eTABCRxfKxkPH7vE/U5qclgq/jXMM+gOagQKk/QmYAOwX6vAmaZgMshtiVKgXz0RgP9YGlmtFC5Eu3txX3MtWVYWKXl4RNhWGXExTqR89uWiHx041ghyQ7LkvGTuIQDKP5TRAAzHPOkoaMQ4o5H+NXXSGj84Ff12XufV3jRHsUCHlku6OC1bp+f811RBbE14dHHgqwvq8m3RhjT+dyJ1HUpuC5WpHpf3lFWqTOJPr70iCV+jBii9BUYnifQplxKPcHl6IjILwX7NHXWl6xTE8Quk9ctZfn5OGsgb7vBYLnq0wvhEKhRluj/IrHzfAyVPGp6inhHMDxCPzWy/5KK8z3dBpZxUr+CpZ5f5O6dAiF6nFKi/ROaFmZDBtoncM3gcJ6dsQinH8AzXQ4SKnrnNmZGJ7+uOyaNbASv1+U8J1WHdy+RyCfx0cNR/GDdxyNl4e6PI0bfxWFAWpN1dBYzS7jJ/UOCPJV6vfh8DCsr6TxENAqNDBp/FvOHepOwy/81+9663Im9/f1lxMYrRDHGOfEtPvCr/8ThhMDNWs1Yxgwgg2t9r6feuFq3yPLImb7fvj5+8Tt4CxpHJBNtnlbdRs1cNcpYQirM2KYLDE+VBihTuWB/S9Tj20YaRnMEtxCVq8ZiDdM1sU3Uw5AqvA4YHQjCeKr0ZqPVJTuVNnCqJ2xLUcGH+ikEE+6dIxV6F0Ah3byunzTQcz6CLYMTOtbRSVNh96FIUGdYYne5KgkRQ9ciMeTvNT5qbv4zKEHXQdOC3faUqWSTJJhF81wB6I0YTQ0blrBctoyZ/1lfTmR60Hopmv57m5JznBJxkL2E53Or8pQt4Cm/vvDWJX7WgNAvaSyV/V1+kuKTcNu1Ips0NCJprJopauSb/WQpUmW/lWYRQcXTjNR8izQnUGXWYHLFc6IP72If7tfAaofUJLL93ePFEiKhpexDgtNw+agtCPCamPW6l62gfwWpNN03ycA2H7JD3MDSSnclu/7G1KeI7tr1dBr9y4hgCwF768s7tFaEvW35tL1FaxUSnmzXPdWBEo8eKj9SLjA9LwUoQpMk0AqeVzJ+upCHw739zm+AfVZSyvBRYzcqPql0ALz5sVA4QwgQlPPIMKt+wl/BW8F6f0up4MMyNwIoua8ia25i4vuuQnUhbzNnylzU4pPDPca1tgC0miOmKjUfJjwGNbK74JcaH17abs6R9IOiWpEnlHqmZ0luDlIvU0nNrePRLlBEr3yADTCBXZSOdYRuJJENjwtLIXIjpb3WoHJtuKd5kKiV9iUzCiL8JmfXrhMXzoUCXcaVeCWB9EAcWlrxUUah19WWd0EQj1xn7Oz+r2sQ6QIopDd4c84unIVca0ohuIuEmhd7BPwuCyvUMh1blsXYKv5Cb71+nnpM0YFf8yE4CPCr90PYtzXBcyzuE+IiN0bkObAv2TtgGt+n85qXK2sYZ4Iy+mzzN2QJ70ISd/2QpWgCwvKhViFZlVohUZoTnh2L+mRtB8WdAHszSlbG7mjFT3mt7yEFmbWKVH8L61M1wji7XSNwd13h8drJIvSbvvlDeHpzzkURmMDRtbSHhlNafh1fzLOu+a7foQ+hfHu1BX2/guYQ4tCsn+oYknKSjZJoRvZh479uiEBGH8t/R5q4XgyyOJHs5ergRKEVFJQGbLFrLdW7G3M6z3prLS+FC58ngmzbH9k7LfxgWWFV0S1BuuF6HHAVUz3SUpgovsKkC9jGIpeYJas5pFnLZ8FJEdxkMksaEGowg5arIF+02Ip/iWJQXH1hkqMkOlFWnaHndEfhBxowmTO4lzP4rW5uNLpedaMhlvpBl4Z7pMCP72w30wEy28XyNyDGlSfDyTiFqyO4TQOkq/DPiDcpyZvDFRAN+XQb3LYnJuafBYVB0BoHH4F8WY6mX0LzIXknvxNvmSoNpuWyrdZXb58SjRs0YR5FPtjf2pJHsJnpf8L/E0O0RL+PUX+FwAA//9QSwcIvI9b2aIJAACrDAAAUEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wdWIUx8kSc0gAAOBX+e9qyhKiHf6qaU1siUiCJG6WTtC2aDSefmqOH6XlPyNN/0AIoX7w9xSJWy6Z/9OAN6hDCBG8Gb7qZwido99WRidnMPcu88vl/pVa+0LJZ+arWJXJQ22XMucX4YCCErtpIY6wmhWBU64McIm3jXVbtUwLSsUdwGI0tj+DteoBJEa71NVPINaErcQMx8MR7FLSG2/dGIjInGI5gdeqJxv1quBST/zKD195fQapuyacTySucSeuOQoyvKp6TsFyRuW906whvffPXfOu0iLctbf/Am5Eqw9zjzluXu+XI/IOQ/WASj/aEP8qcATK4XtR4cx/5PJw5mkzAxy+HzoX095hTmg47wpnFN5rTpO1ousv/AP16Lodm3o5KEH38RoDfLhuB+7YKw455bJkP4kWyKgzyJm+6A8NXi/H/fx5OqIcu2l40AKG1e+vCDs68otlfyZ3jnrkqcRMTvotkK3RrfOlf6LSVSXDdDyUnw7cTW4HIFBTO9MElu17M7J1xobKbpwDeVxgEgGyHG3pfmI+Bui2CpdD+fiZE0S636hS/6X4qInZarTlZqlp+rgagq3pU5PI7K7kwlX/KYq+3lPPErOe8GA6kXyqueNcZnahR7q9zlL3VBhJilBViGkmD3Q2W9W2P9UzbpM8V+crhDGruhMXqTgUuqLO3ssub16scGm3g7a7VM8wFjcpKNzIqqwRsZuW3ZZUjnESqna+ogv7hSwvl1/tc3i16zqMJq/XInJ9mcLOcgi6nbPY379/Cjw0/Sb+m85T/21m/F8AAAD//1BLBwjgjOdEVwIAAOUCAABQSwECFAAUAAgACAAAAAAAvI9b2aIJAACrDAAALwAAAAAAAAAAAAAAAAAAAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wZW1QSwECFAAUAAgACAAAAAAA4IznRFcCAADlAgAALwAAAAAAAAAAAAAAAAD/CQAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wdWJQSwUGAAAAAAIAAgC6AAAAswwAAAAA\",\"filenames\":[\"id_rsa_8e9a0707-02ec-483d-abb7-1c45d199c116.zip\",\"id_rsa_8e9a0707-02ec-483d-abb7-1c45d199c116.pem\",\"id_rsa_8e9a0707-02ec-483d-abb7-1c45d199c116.pub\"]}\n","ca_cert_pem":null,"client_cert_pem":null,"client_key_pem":null,"id":"http://localhost:8080/api/v1/ssh/8e9a0707-02ec-483d-abb7-1c45d199c116/download?part=both\u0026mode=json","insecure":null,"method":null,"request_body":null,"request_headers":{"Accept":"application/json","X-ORG-KEY":"org_lnJwmyyWH7JC-JgZo5v3Kw","X-ORG-SECRET":"fqd9yebGMfK6h5HSgWn4sXrwr9xlFbvbIYtNylRElMQ"},"request_timeout_ms":null,"response_body":"{\"id\":\"8e9a0707-02ec-483d-abb7-1c45d199c116\",\"name\":\"CI deploy key 1\",\"fingerprint\":\"SHA256:VxjPg+mm+WKYizRKUHSxB95D5lo961XcYZrnpQerTm0\",\"zip_base64\":\"UEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wZW1sl7USrAoCBXO+4ubUFm7BBrgzyKAZMLi7fP3Wu5u+k56sq5P+zz/jRFm1/rge+8d21YD9in90Mf77AKaqajqrciyr82wlsm/xhlfVIPo2BZynuyaBvnEGx9Zcv4amUCfeF6AmHsSKRzbFWMDV4lETjr/0UtfjZx/fzbYHb1twYpo3+4sXXloaF+G+2WnGi81qLLHi+LJr3BrVgysCJAOeJjOkLMo6ZGLlvJLdpUQ7Yb7yU/uqVEmXZPwxgxZt8rBsE+ucvayci/3DCscVAYZtPNfkJ5C7hF0qbZDX7isjlqEQQHxgqCPNF6MyB6j0WOVjshPpTN/ArE4Ei3pbTYFY+FzGiYHq74EoLTuVDhWrss903uTF65HVcaBYMYbOwo4SUrDhamHb7ZhjigG/BPYAswMp0ExDfEp+PI2LPlaNzPYXZOeL4CmJ0qvFWz5SaoxIYxWSF3YM9KWVA9dHn6B0CKDuGqO8rNfZ5iA42XV8AeSWJ8YMUqomr2Cqm+erkftB3UdbSsvgbI+SHTUZzAqlsxGoQFq0G9bGxmiWbM0Aa6ZzcyE62c78CRbuL7XhsNU3KZhFNZTj/IW0Q0x5faBD11YMwEFOloSFKRaRJVTpUTi5Hzb1HpKaDRluohgxdKxTeGNOwLp0ts/IkWty5INgwnGyD1TNrR33jeF9nwyR8qHaipVydb7L/oN1jIbFKGrQoNn0RTnMNKTNr9p3yC/fW8wLuAmol2sT7RA20EOKBh+8MdNpTb2jFTUjp7ccNxfHYcTwFjvQhP62TFphbY2G6o1nL5EFWOcfhdnk6aHsG5ytz543aWgDovYPIZ4wP9mN4yVhvWGHSfM0FxkC6Mkw2xpOfikxYLlIhxrxxb3xRJr04PeNHHslU8utkYLgQ+haVwiY6nZxTkZSTwgpKbTfb19wRtsEBkAcFxaYSMNWn3xi99wkWhO1WTdadadUekVkRL86iRFGTT9VXSn7lSa3hFWKwxlFgjXQ4cYk92AuBc5Z2RLNr/kRU1B+tWbmlnmal7B8wodkvlPMeJyPICd+EMMjbvkh47IKjDy8J8p4OGk+4LyTdltZHofivji86SR7yXznObEinfrKWKh3LtEVRxoUGYph444CA5rSWGWVHA2Pvs+7i6B8bsOJ1UwtKiAkOAOh2MWiK2TlnmIxU10HK0NhqreymQVvwoDd0jXP/wSaqTGqVPoDT/Aood+7Y10hcWcDOYn7S6Vah7ahpX0o7DDgz865QevAJaYACSm12Y4HDwNTKdFRi7wa00ry1rvqYldtCKEjm/i5OE8R4P04itNJ0MNOZjIa12eTABCRxfKxkPH7vE/U5qclgq/jXMM+gOagQKk/QmYAOwX6vAmaZgMshtiVKgXz0RgP9YGlmtFC5Eu3txX3MtWVYWKXl4RNhWGXExTqR89uWiHx041ghyQ7LkvGTuIQDKP5TRAAzHPOkoaMQ4o5H+NXXSGj84Ff12XufV3jRHsUCHlku6OC1bp+f811RBbE14dHHgqwvq8m3RhjT+dyJ1HUpuC5WpHpf3lFWqTOJPr70iCV+jBii9BUYnifQplxKPcHl6IjILwX7NHXWl6xTE8Quk9ctZfn5OGsgb7vBYLnq0wvhEKhRluj/IrHzfAyVPGp6inhHMDxCPzWy/5KK8z3dBpZxUr+CpZ5f5O6dAiF6nFKi/ROaFmZDBtoncM3gcJ6dsQinH8AzXQ4SKnrnNmZGJ7+uOyaNbASv1+U8J1WHdy+RyCfx0cNR/GDdxyNl4e6PI0bfxWFAWpN1dBYzS7jJ/UOCPJV6vfh8DCsr6TxENAqNDBp/FvOHepOwy/81+9663Im9/f1lxMYrRDHGOfEtPvCr/8ThhMDNWs1Yxgwgg2t9r6feuFq3yPLImb7fvj5+8Tt4CxpHJBNtnlbdRs1cNcpYQirM2KYLDE+VBihTuWB/S9Tj20YaRnMEtxCVq8ZiDdM1sU3Uw5AqvA4YHQjCeKr0ZqPVJTuVNnCqJ2xLUcGH+ikEE+6dIxV6F0Ah3byunzTQcz6CLYMTOtbRSVNh96FIUGdYYne5KgkRQ9ciMeTvNT5qbv4zKEHXQdOC3faUqWSTJJhF81wB6I0YTQ0blrBctoyZ/1lfTmR60Hopmv57m5JznBJxkL2E53Or8pQt4Cm/vvDWJX7WgNAvaSyV/V1+kuKTcNu1Ips0NCJprJopauSb/WQpUmW/lWYRQcXTjNR8izQnUGXWYHLFc6IP72If7tfAaofUJLL93ePFEiKhpexDgtNw+agtCPCamPW6l62gfwWpNN03ycA2H7JD3MDSSnclu/7G1KeI7tr1dBr9y4hgCwF768s7tFaEvW35tL1FaxUSnmzXPdWBEo8eKj9SLjA9LwUoQpMk0AqeVzJ+upCHw739zm+AfVZSyvBRYzcqPql0ALz5sVA4QwgQlPPIMKt+wl/BW8F6f0up4MMyNwIoua8ia25i4vuuQnUhbzNnylzU4pPDPca1tgC0miOmKjUfJjwGNbK74JcaH17abs6R9IOiWpEnlHqmZ0luDlIvU0nNrePRLlBEr3yADTCBXZSOdYRuJJENjwtLIXIjpb3WoHJtuKd5kKiV9iUzCiL8JmfXrhMXzoUCXcaVeCWB9EAcWlrxUUah19WWd0EQj1xn7Oz+r2sQ6QIopDd4c84unIVca0ohuIuEmhd7BPwuCyvUMh1blsXYKv5Cb71+nnpM0YFf8yE4CPCr90PYtzXBcyzuE+IiN0bkObAv2TtgGt+n85qXK2sYZ4Iy+mzzN2QJ70ISd/2QpWgCwvKhViFZlVohUZoTnh2L+mRtB8WdAHszSlbG7mjFT3mt7yEFmbWKVH8L61M1wji7XSNwd13h8drJIvSbvvlDeHpzzkURmMDRtbSHhlNafh1fzLOu+a7foQ+hfHu1BX2/guYQ4tCsn+oYknKSjZJoRvZh479uiEBGH8t/R5q4XgyyOJHs5ergRKEVFJQGbLFrLdW7G3M6z3prLS+FC58ngmzbH9k7LfxgWWFV0S1BuuF6HHAVUz3SUpgovsKkC9jGIpeYJas5pFnLZ8FJEdxkMksaEGowg5arIF+02Ip/iWJQXH1hkqMkOlFWnaHndEfhBxowmTO4lzP4rW5uNLpedaMhlvpBl4Z7pMCP72w30wEy28XyNyDGlSfDyTiFqyO4TQOkq/DPiDcpyZvDFRAN+XQb3LYnJuafBYVB0BoHH4F8WY6mX0LzIXknvxNvmSoNpuWyrdZXb58SjRs0YR5FPtjf2pJHsJnpf8L/E0O0RL+PUX+FwAA//9QSwcIvI9b2aIJAACrDAAAUEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wdWIUx8kSc0gAAOBX+e9qyhKiHf6qaU1siUiCJG6WTtC2aDSefmqOH6XlPyNN/0AIoX7w9xSJWy6Z/9OAN6hDCBG8Gb7qZwido99WRidnMPcu88vl/pVa+0LJZ+arWJXJQ22XMucX4YCCErtpIY6wmhWBU64McIm3jXVbtUwLSsUdwGI0tj+DteoBJEa71NVPINaErcQMx8MR7FLSG2/dGIjInGI5gdeqJxv1quBST/zKD195fQapuyacTySucSeuOQoyvKp6TsFyRuW906whvffPXfOu0iLctbf/Am5Eqw9zjzluXu+XI/IOQ/WASj/aEP8qcATK4XtR4cx/5PJw5mkzAxy+HzoX095hTmg47wpnFN5rTpO1ousv/AP16Lodm3o5KEH38RoDfLhuB+7YKw455bJkP4kWyKgzyJm+6A8NXi/H/fx5OqIcu2l40AKG1e+vCDs68otlfyZ3jnrkqcRMTvotkK3RrfOlf6LSVSXDdDyUnw7cTW4HIFBTO9MElu17M7J1xobKbpwDeVxgEgGyHG3pfmI+Bui2CpdD+fiZE0S636hS/6X4qInZarTlZqlp+rgagq3pU5PI7K7kwlX/KYq+3lPPErOe8GA6kXyqueNcZnahR7q9zlL3VBhJilBViGkmD3Q2W9W2P9UzbpM8V+crhDGruhMXqTgUuqLO3ssub16scGm3g7a7VM8wFjcpKNzIqqwRsZuW3ZZUjnESqna+ogv7hSwvl1/tc3i16zqMJq/XInJ9mcLOcgi6nbPY379/Cjw0/Sb+m85T/21m/F8AAAD//1BLBwjgjOdEVwIAAOUCAABQSwECFAAUAAgACAAAAAAAvI9b2aIJAACrDAAALwAAAAAAAAAAAAAAAAAAAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wZW1QSwECFAAUAAgACAAAAAAA4IznRFcCAADlAgAALwAAAAAAAAAAAAAAAAD/CQAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wdWJQSwUGAAAAAAIAAgC6AAAAswwAAAAA\",\"filenames\":[\"id_rsa_8e9a0707-02ec-483d-abb7-1c45d199c116.zip\",\"id_rsa_8e9a0707-02ec-483d-abb7-1c45d199c116.pem\",\"id_rsa_8e9a0707-02ec-483d-abb7-1c45d199c116.pub\"]}\n","response_body_base64":"eyJpZCI6IjhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNiIsIm5hbWUiOiJDSSBkZXBsb3kga2V5IDEiLCJmaW5nZXJwcmludCI6IlNIQTI1NjpWeGpQZyttbStXS1lpelJLVUhTeEI5NUQ1bG85NjFYY1lacm5wUWVyVG0wIiwiemlwX2Jhc2U2NCI6IlVFc0RCQlFBQ0FBSUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBdkFBQUFhV1JmY25OaFh6aGxPV0V3TnpBM0xUQXlaV010TkRnelpDMWhZbUkzTFRGak5EVmtNVGs1WXpFeE5pNXdaVzFzbDdVU3JBb0NCWE8rNHViVUZtN0JCcmd6eUtBWk1MaTdmUDNXdTV1K2s1NnNxNVArenovalJGbTEvcmdlKzhkMjFZRDlpbjkwTWY3N0FLYXFhanFyY2l5cjgyd2xzbS94aGxmVklQbzJCWnludXlhQnZuRUd4OVpjdjRhbVVDZmVGNkFtSHNTS1J6YkZXTURWNGxFVGpyLzBVdGZqWngvZnpiWUhiMXR3WXBvMys0c1hYbG9hRitHKzJXbkdpODFxTExIaStMSnIzQnJWZ3lzQ0pBT2VKak9rTE1vNlpHTGx2SkxkcFVRN1liN3lVL3VxVkVtWFpQd3hneFp0OHJCc0UrdWN2YXljaS8zRENzY1ZBWVp0UE5ma0o1QzdoRjBxYlpEWDdpc2pscUVRUUh4Z3FDUE5GNk15QjZqMFdPVmpzaFBwVE4vQXJFNEVpM3BiVFlGWStGekdpWUhxNzRFb0xUdVZEaFdyc3M5MDN1VEY2NUhWY2FCWU1ZYk93bzRTVXJEaGFtSGI3WmhqaWdHL0JQWUFzd01wMEV4RGZFcCtQSTJMUGxhTnpQWVhaT2VMNENtSjBxdkZXejVTYW94SVl4V1NGM1lNOUtXVkE5ZEhuNkIwQ0tEdUdxTzhyTmZaNWlBNDJYVjhBZVNXSjhZTVVxb21yMkNxbStlcmtmdEIzVWRiU3N2Z2JJK1NIVFVaekFxbHN4R29RRnEwRzliR3htaVdiTTBBYTZaemN5RTYyYzc4Q1JidUw3WGhzTlUzS1poRk5aVGovSVcwUTB4NWZhQkQxMVlNd0VGT2xvU0ZLUmFSSlZUcFVUaTVIemIxSHBLYURSbHVvaGd4ZEt4VGVHTk93THAwdHMvSWtXdHk1SU5nd25HeUQxVE5yUjMzamVGOW53eVI4cUhhaXBWeWRiN0wvb04xakliRktHclFvTm4wUlRuTU5LVE5yOXAzeUMvZlc4d0x1QW1vbDJzVDdSQTIwRU9LQmgrOE1kTnBUYjJqRlRVanA3Y2NOeGZIWWNUd0ZqdlFoUDYyVEZwaGJZMkc2bzFuTDVFRldPY2ZoZG5rNmFIc0c1eXR6NTQzYVdnRG92WVBJWjR3UDltTjR5Vmh2V0dIU2ZNMEZ4a0M2TWt3MnhwT2Zpa3hZTGxJaHhyeHhiM3hSSnIwNFBlTkhIc2xVOHV0a1lMZ1EraGFWd2lZNm5aeFRrWlNUd2dwS2JUZmIxOXdSdHNFQmtBY0Z4YVlTTU5XbjN4aTk5d2tXaE8xV1RkYWRhZFVla1ZrUkw4NmlSRkdUVDlWWFNuN2xTYTNoRldLd3hsRmdqWFE0Y1lrOTJBdUJjNVoyUkxOci9rUlUxQit0V2JtbG5tYWw3Qjh3b2RrdmxQTWVKeVBJQ2QrRU1NamJ2a2g0N0lLakR5OEo4cDRPR2srNEx5VGRsdFpIb2ZpdmppODZTUjd5WHpuT2JFaW5mcktXS2gzTHRFVlJ4b1VHWXBoNDQ0Q0E1clNXR1dWSEEyUHZzKzdpNkI4YnNPSjFVd3RLaUFrT0FPaDJNV2lLMlRsbm1JeFUxMEhLME5ocXJleW1RVnZ3b0RkMGpYUC93U2FxVEdxVlBvRFQvQW9vZCs3WTEwaGNXY0RPWW43UzZWYWg3YWhwWDBvN0REZ3o4NjVRZXZBSmFZQUNTbTEyWTRIRHdOVEtkRlJpN3dhMDByeTFydnFZbGR0Q0tFam0vaTVPRThSNFAwNGl0TkowTU5PWmpJYTEyZVRBQkNSeGZLeGtQSDd2RS9VNXFjbGdxL2pYTU0rZ09hZ1FLay9RbVlBT3dYNnZBbWFaZ01zaHRpVktnWHowUmdQOVlHbG10RkM1RXUzdHhYM010V1ZZV0tYbDRSTmhXR1hFeFRxUjg5dVdpSHgwNDFnaHlRN0xrdkdUdUlRREtQNVRSQUF6SFBPa29hTVE0bzVIK05YWFNHajg0RmYxMlh1ZlYzalJIc1VDSGxrdTZPQzFicCtmODExUkJiRTE0ZEhIZ3F3dnE4bTNSaGpUK2R5SjFIVXB1QzVXcEhwZjNsRldxVE9KUHI3MGlDVitqQmlpOUJVWW5pZlFwbHhLUGNIbDZJaklMd1g3TkhYV2w2eFRFOFF1azljdFpmbjVPR3NnYjd2QllMbnEwd3ZoRUtoUmx1ai9Jckh6ZkF5VlBHcDZpbmhITUR4Q1B6V3kvNUtLOHozZEJwWnhVcitDcFo1ZjVPNmRBaUY2bkZLaS9ST2FGbVpEQnRvbmNNM2djSjZkc1Fpbkg4QXpYUTRTS25ybk5tWkdKNyt1T3lhTmJBU3YxK1U4SjFXSGR5K1J5Q2Z4MGNOUi9HRGR4eU5sNGU2UEkwYmZ4V0ZBV3BOMWRCWXpTN2pKL1VPQ1BKVjZ2Zmg4RENzcjZUeEVOQXFOREJwL0Z2T0hlcE93eS84MSs5NjYzSW05L2YxbHhNWXJSREhHT2ZFdFB2Q3IvOFRoaE1ETldzMVl4Z3dnZzJ0OXI2ZmV1RnEzeVBMSW1iN2Z2ajUrOFR0NEN4cEhKQk50bmxiZFJzMWNOY3BZUWlyTTJLWUxERStWQmloVHVXQi9TOVRqMjBZYVJuTUV0eENWcThaaURkTTFzVTNVdzVBcXZBNFlIUWpDZUtyMFpxUFZKVHVWTm5DcUoyeExVY0dIK2lrRUUrNmRJeFY2RjBBaDNieXVuelRRY3o2Q0xZTVRPdGJSU1ZOaDk2RklVR2RZWW5lNUtna1JROWNpTWVUdk5UNXFidjR6S0VIWFFkT0MzZmFVcVdTVEpKaEY4MXdCNkkwWVRRMGJsckJjdG95Wi8xbGZUbVI2MEhvcG12NTdtNUp6bkJKeGtMMkU1M09yOHBRdDRDbS92dkRXSlg3V2dOQXZhU3lWL1YxK2t1S1RjTnUxSXBzME5DSnBySm9wYXVTYi9XUXBVbVcvbFdZUlFjWFRqTlI4aXpRblVHWFdZSExGYzZJUDcySWY3dGZBYW9mVUpMTDkzZVBGRWlLaHBleERndE53K2FndENQQ2FtUFc2bDYyZ2Z3V3BOTjAzeWNBMkg3SkQzTURTU25jbHUvN0cxS2VJN3RyMWRCcjl5NGhnQ3dGNzY4czd0RmFFdlczNXRMMUZheFVTbm16WFBkV0JFbzhlS2o5U0xqQTlMd1VvUXBNazBBcWVWekordXBDSHc3Mzl6bStBZlZaU3l2QlJZemNxUHFsMEFMejVzVkE0UXdnUWxQUElNS3Qrd2wvQlc4RjZmMHVwNE1NeU53SW91YThpYTI1aTR2dXVRblVoYnpObnlselU0cFBEUGNhMXRnQzBtaU9tS2pVZkpqd0dOYks3NEpjYUgxN2FiczZSOUlPaVdwRW5sSHFtWjBsdURsSXZVMG5OcmVQUkxsQkVyM3lBRFRDQlhaU09kWVJ1SkpFTmp3dExJWElqcGIzV29ISnR1S2Q1a0tpVjlpVXpDaUw4Sm1mWHJoTVh6b1VDWGNhVmVDV0I5RUFjV2xyeFVVYWgxOVdXZDBFUWoxeG43T3orcjJzUTZRSW9wRGQ0Yzg0dW5JVmNhMG9odUl1RW1oZDdCUHd1Q3l2VU1oMWJsc1hZS3Y1Q2I3MStubnBNMFlGZjh5RTRDUENyOTBQWXR6WEJjeXp1RStJaU4wYmtPYkF2MlR0Z0d0K244NXFYSzJzWVo0SXkrbXp6TjJRSjcwSVNkLzJRcFdnQ3d2S2hWaUZabFZvaFVab1RuaDJMK21SdEI4V2RBSHN6U2xiRzdtakZUM210N3lFRm1iV0tWSDhMNjFNMXdqaTdYU053ZDEzaDhkckpJdlNidnZsRGVIcHp6a1VSbU1EUnRiU0hobE5hZmgxZnpMT3UrYTdmb1EraGZIdTFCWDIvZ3VZUTR0Q3NuK29Za25LU2paSm9SdlpoNDc5dWlFQkdIOHQvUjVxNFhneXlPSkhzNWVyZ1JLRVZGSlFHYkxGckxkVzdHM002ejNwckxTK0ZDNThuZ216Ykg5azdMZnhnV1dGVjBTMUJ1dUY2SEhBVlV6M1NVcGdvdnNLa0M5akdJcGVZSmFzNXBGbkxaOEZKRWR4a01rc2FFR293ZzVhcklGKzAySXAvaVdKUVhIMWhrcU1rT2xGV25hSG5kRWZoQnhvd21UTzRselA0clc1dU5McGVkYU1obHZwQmw0WjdwTUNQNzJ3MzB3RXkyOFh5TnlER2xTZkR5VGlGcXlPNFRRT2txL0RQaURjcHladkRGUkFOK1hRYjNMWW5KdWFmQllWQjBCb0hINEY4V1k2bVgwTHpJWGtudnhOdm1Tb05wdVd5cmRaWGI1OFNqUnMwWVI1RlB0amYycEpIc0pucGY4TC9FME8wUkwrUFVYK0Z3QUEvLzlRU3djSXZJOWIyYUlKQUFDckRBQUFVRXNEQkJRQUNBQUlBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQXZBQUFBYVdSZmNuTmhYemhsT1dFd056QTNMVEF5WldNdE5EZ3paQzFoWW1JM0xURmpORFZrTVRrNVl6RXhOaTV3ZFdJVXg4a1NjMGdBQU9CWCtlOXF5aEtpSGY2cWFVMXNpVWlDSkc2V1R0QzJhRFNlZm1xT0g2WGxQeU5OLzBBSW9YN3c5eFNKV3k2Wi85T0FONmhEQ0JHOEdiN3Fad2lkbzk5V1JpZG5NUGN1ODh2bC9wVmErMExKWithcldKWEpRMjJYTXVjWDRZQ0NFcnRwSVk2d21oV0JVNjRNY0ltM2pYVmJ0VXdMU3NVZHdHSTB0aitEdGVvQkpFYTcxTlZQSU5hRXJjUU14OE1SN0ZMU0cyL2RHSWpJbkdJNWdkZXFKeHYxcXVCU1QvektEMTk1ZlFhcHV5YWNUeVN1Y1NldU9Rb3l2S3A2VHNGeVJ1VzkwNndodmZmUFhmT3UwaUxjdGJmL0FtNUVxdzl6anpsdVh1K1hJL0lPUS9XQVNqL2FFUDhxY0FUSzRYdFI0Y3gvNVBKdzVta3pBeHkrSHpvWDA5NWhUbWc0N3dwbkZONXJUcE8xb3Vzdi9BUDE2TG9kbTNvNUtFSDM4Um9EZkxodUIrN1lLdzQ1NWJKa1A0a1d5S2d6eUptKzZBOE5YaS9IL2Z4NU9xSWN1Mmw0MEFLRzFlK3ZDRHM2OG90bGZ5WjNqbnJrcWNSTVR2b3RrSzNScmZPbGY2TFNWU1hEZER5VW53N2NUVzRISUZCVE85TUVsdTE3TTdKMXhvYkticHdEZVZ4Z0VnR3lIRzNwZm1JK0J1aTJDcGREK2ZpWkUwUzYzNmhTLzZYNHFJblphclRsWnFscCtyZ2FncTNwVTVQSTdLN2t3bFgvS1lxKzNsUFBFck9lOEdBNmtYeXF1ZU5jWm5haFI3cTl6bEwzVkJoSmlsQlZpR2ttRDNRMlc5VzJQOVV6YnBNOFYrY3JoREdydWhNWHFUZ1V1cUxPM3NzdWIxNnNjR20zZzdhN1ZNOHdGamNwS056SXFxd1JzWnVXM1paVWpuRVNxbmErb2d2N2hTd3ZsMS90YzNpMTZ6cU1KcS9YSW5KOW1jTE9jZ2k2bmJQWTM3OS9DancwL1NiK204NVQvMjFtL0Y4QUFBRC8vMUJMQndqZ2pPZEVWd0lBQU9VQ0FBQlFTd0VDRkFBVUFBZ0FDQUFBQUFBQXZJOWIyYUlKQUFDckRBQUFMd0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFhV1JmY25OaFh6aGxPV0V3TnpBM0xUQXlaV010TkRnelpDMWhZbUkzTFRGak5EVmtNVGs1WXpFeE5pNXdaVzFRU3dFQ0ZBQVVBQWdBQ0FBQUFBQUE0SXpuUkZjQ0FBRGxBZ0FBTHdBQUFBQUFBQUFBQUFBQUFBRC9DUUFBYVdSZmNuTmhYemhsT1dFd056QTNMVEF5WldNdE5EZ3paQzFoWW1JM0xURmpORFZrTVRrNVl6RXhOaTV3ZFdKUVN3VUdBQUFBQUFJQUFnQzZBQUFBc3d3QUFBQUEiLCJmaWxlbmFtZXMiOlsiaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi56aXAiLCJpZF9yc2FfOGU5YTA3MDctMDJlYy00ODNkLWFiYjctMWM0NWQxOTljMTE2LnBlbSIsImlkX3JzYV84ZTlhMDcwNy0wMmVjLTQ4M2QtYWJiNy0xYzQ1ZDE5OWMxMTYucHViIl19Cg==","response_headers":{"Content-Security-Policy":"default-src 'self'; base-uri 'self'; form-action 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' http://localhost:5173; style-src 'self' 'unsafe-inline' http://localhost:5173 https://fonts.googleapis.com; img-src 'self' data: blob:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' http://localhost:5173 ws://localhost:5173 ws://localhost:8080; frame-ancestors 'none'","Content-Type":"application/json","Date":"Sat, 01 Nov 2025 07:04:39 GMT","Permissions-Policy":"geolocation=(), camera=(), microphone=(), interest-cohort=()","Referrer-Policy":"strict-origin-when-cross-origin","Vary":"Origin","X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","X-Ratelimit-Limit":"100","X-Ratelimit-Remaining":"96","X-Ratelimit-Reset":"1761980700"},"retry":null,"status_code":200,"url":"http://localhost:8080/api/v1/ssh/8e9a0707-02ec-483d-abb7-1c45d199c116/download?part=both\u0026mode=json"},"sensitive_attributes":[[{"type":"get_attr","value":"request_headers"},{"type":"index","value":{"value":"X-ORG-KEY","type":"string"}}],[{"type":"get_attr","value":"request_headers"},{"type":"index","value":{"value":"X-ORG-SECRET","type":"string"}}]]}]},{"module":"module.ssh[\"key1\"]","mode":"managed","type":"autoglue_ssh_key","name":"this","provider":"provider[\"glueops/autoglue/autoglue\"]","instances":[{"schema_version":0,"attributes":{"bits":4096,"comment":"deploy1@autoglue","created_at":"2025-11-01T07:04:39Z","fingerprint":"SHA256:VxjPg+mm+WKYizRKUHSxB95D5lo961XcYZrnpQerTm0","id":"8e9a0707-02ec-483d-abb7-1c45d199c116","name":"CI deploy key 1","private_key_pem":null,"public_key":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDN7NbCCLUqyhUFIpEznbNhvRg2mHMskfu/iV74kS7mvhc/v03CPheJad1rAiu50+5Ow8+ZKyrjmimw9Ph5Jp8vDlHNu8xio8AkDmvjiq0kGteGZETr368z2ZoDYBDpk1wIdvF8XxBZysKiPMjt/x/pg4xWPaJxZ+Nk2+lJt+l604AO7Bcs8vLChRn9GpaRoWz9KO2v0R9YNX8JUsifwJ6celXYXI1/IwCjpChNUyC/XdeU8hpgM7Au/f4h3L/slu8eTYSB+VsoIwITDIYiebsARj+949dnoM/SCoCOy6ljv35PnfKlD8f+nz8Jro5IkFc42HWk9P4CnDkLsXsqCpKo4VoufWI14VJaT39Pwe7gqdTnsr/vGHftJuUoCK7kEZFBQP4GrJjcvoWChJ72DEIKCcF3+Q4mp80sE9LsZAhmYyDbxueD7wQ+IA/edekU8kv6H2RFwNe8CQx0M3hSqEtACBNl72ogse691bxDmhyG7aaSOD0H9BtlZ4wR5c0OBq55BxRaKG1bok/8tFkctj+6uhbHdBUBHxu2nW5wkZdT75kEEZSCLEm7HHfiWVmZcc7uOAAVwinF+U7eT0ndjbYvz4yKV5+anz8mnMiWTV1y2PdJUGiGrCwQ9bQva4VeZT7HcxCMwqTwchvqjN+exHjjTUtKo9UkOXE0zwcA8nz+Gw== deploy1@autoglue","type":"rsa","updated_at":"2025-11-01T07:04:39Z"},"sensitive_attributes":[[{"type":"get_attr","value":"private_key_pem"}]]}]},{"module":"module.ssh[\"key1\"]","mode":"managed","type":"local_sensitive_file","name":"zip","provider":"provider[\"registry.opentofu.org/hashicorp/local\"]","instances":[{"index_key":0,"schema_version":0,"attributes":{"content":null,"content_base64":"UEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wZW1sl7USrAoCBXO+4ubUFm7BBrgzyKAZMLi7fP3Wu5u+k56sq5P+zz/jRFm1/rge+8d21YD9in90Mf77AKaqajqrciyr82wlsm/xhlfVIPo2BZynuyaBvnEGx9Zcv4amUCfeF6AmHsSKRzbFWMDV4lETjr/0UtfjZx/fzbYHb1twYpo3+4sXXloaF+G+2WnGi81qLLHi+LJr3BrVgysCJAOeJjOkLMo6ZGLlvJLdpUQ7Yb7yU/uqVEmXZPwxgxZt8rBsE+ucvayci/3DCscVAYZtPNfkJ5C7hF0qbZDX7isjlqEQQHxgqCPNF6MyB6j0WOVjshPpTN/ArE4Ei3pbTYFY+FzGiYHq74EoLTuVDhWrss903uTF65HVcaBYMYbOwo4SUrDhamHb7ZhjigG/BPYAswMp0ExDfEp+PI2LPlaNzPYXZOeL4CmJ0qvFWz5SaoxIYxWSF3YM9KWVA9dHn6B0CKDuGqO8rNfZ5iA42XV8AeSWJ8YMUqomr2Cqm+erkftB3UdbSsvgbI+SHTUZzAqlsxGoQFq0G9bGxmiWbM0Aa6ZzcyE62c78CRbuL7XhsNU3KZhFNZTj/IW0Q0x5faBD11YMwEFOloSFKRaRJVTpUTi5Hzb1HpKaDRluohgxdKxTeGNOwLp0ts/IkWty5INgwnGyD1TNrR33jeF9nwyR8qHaipVydb7L/oN1jIbFKGrQoNn0RTnMNKTNr9p3yC/fW8wLuAmol2sT7RA20EOKBh+8MdNpTb2jFTUjp7ccNxfHYcTwFjvQhP62TFphbY2G6o1nL5EFWOcfhdnk6aHsG5ytz543aWgDovYPIZ4wP9mN4yVhvWGHSfM0FxkC6Mkw2xpOfikxYLlIhxrxxb3xRJr04PeNHHslU8utkYLgQ+haVwiY6nZxTkZSTwgpKbTfb19wRtsEBkAcFxaYSMNWn3xi99wkWhO1WTdadadUekVkRL86iRFGTT9VXSn7lSa3hFWKwxlFgjXQ4cYk92AuBc5Z2RLNr/kRU1B+tWbmlnmal7B8wodkvlPMeJyPICd+EMMjbvkh47IKjDy8J8p4OGk+4LyTdltZHofivji86SR7yXznObEinfrKWKh3LtEVRxoUGYph444CA5rSWGWVHA2Pvs+7i6B8bsOJ1UwtKiAkOAOh2MWiK2TlnmIxU10HK0NhqreymQVvwoDd0jXP/wSaqTGqVPoDT/Aood+7Y10hcWcDOYn7S6Vah7ahpX0o7DDgz865QevAJaYACSm12Y4HDwNTKdFRi7wa00ry1rvqYldtCKEjm/i5OE8R4P04itNJ0MNOZjIa12eTABCRxfKxkPH7vE/U5qclgq/jXMM+gOagQKk/QmYAOwX6vAmaZgMshtiVKgXz0RgP9YGlmtFC5Eu3txX3MtWVYWKXl4RNhWGXExTqR89uWiHx041ghyQ7LkvGTuIQDKP5TRAAzHPOkoaMQ4o5H+NXXSGj84Ff12XufV3jRHsUCHlku6OC1bp+f811RBbE14dHHgqwvq8m3RhjT+dyJ1HUpuC5WpHpf3lFWqTOJPr70iCV+jBii9BUYnifQplxKPcHl6IjILwX7NHXWl6xTE8Quk9ctZfn5OGsgb7vBYLnq0wvhEKhRluj/IrHzfAyVPGp6inhHMDxCPzWy/5KK8z3dBpZxUr+CpZ5f5O6dAiF6nFKi/ROaFmZDBtoncM3gcJ6dsQinH8AzXQ4SKnrnNmZGJ7+uOyaNbASv1+U8J1WHdy+RyCfx0cNR/GDdxyNl4e6PI0bfxWFAWpN1dBYzS7jJ/UOCPJV6vfh8DCsr6TxENAqNDBp/FvOHepOwy/81+9663Im9/f1lxMYrRDHGOfEtPvCr/8ThhMDNWs1Yxgwgg2t9r6feuFq3yPLImb7fvj5+8Tt4CxpHJBNtnlbdRs1cNcpYQirM2KYLDE+VBihTuWB/S9Tj20YaRnMEtxCVq8ZiDdM1sU3Uw5AqvA4YHQjCeKr0ZqPVJTuVNnCqJ2xLUcGH+ikEE+6dIxV6F0Ah3byunzTQcz6CLYMTOtbRSVNh96FIUGdYYne5KgkRQ9ciMeTvNT5qbv4zKEHXQdOC3faUqWSTJJhF81wB6I0YTQ0blrBctoyZ/1lfTmR60Hopmv57m5JznBJxkL2E53Or8pQt4Cm/vvDWJX7WgNAvaSyV/V1+kuKTcNu1Ips0NCJprJopauSb/WQpUmW/lWYRQcXTjNR8izQnUGXWYHLFc6IP72If7tfAaofUJLL93ePFEiKhpexDgtNw+agtCPCamPW6l62gfwWpNN03ycA2H7JD3MDSSnclu/7G1KeI7tr1dBr9y4hgCwF768s7tFaEvW35tL1FaxUSnmzXPdWBEo8eKj9SLjA9LwUoQpMk0AqeVzJ+upCHw739zm+AfVZSyvBRYzcqPql0ALz5sVA4QwgQlPPIMKt+wl/BW8F6f0up4MMyNwIoua8ia25i4vuuQnUhbzNnylzU4pPDPca1tgC0miOmKjUfJjwGNbK74JcaH17abs6R9IOiWpEnlHqmZ0luDlIvU0nNrePRLlBEr3yADTCBXZSOdYRuJJENjwtLIXIjpb3WoHJtuKd5kKiV9iUzCiL8JmfXrhMXzoUCXcaVeCWB9EAcWlrxUUah19WWd0EQj1xn7Oz+r2sQ6QIopDd4c84unIVca0ohuIuEmhd7BPwuCyvUMh1blsXYKv5Cb71+nnpM0YFf8yE4CPCr90PYtzXBcyzuE+IiN0bkObAv2TtgGt+n85qXK2sYZ4Iy+mzzN2QJ70ISd/2QpWgCwvKhViFZlVohUZoTnh2L+mRtB8WdAHszSlbG7mjFT3mt7yEFmbWKVH8L61M1wji7XSNwd13h8drJIvSbvvlDeHpzzkURmMDRtbSHhlNafh1fzLOu+a7foQ+hfHu1BX2/guYQ4tCsn+oYknKSjZJoRvZh479uiEBGH8t/R5q4XgyyOJHs5ergRKEVFJQGbLFrLdW7G3M6z3prLS+FC58ngmzbH9k7LfxgWWFV0S1BuuF6HHAVUz3SUpgovsKkC9jGIpeYJas5pFnLZ8FJEdxkMksaEGowg5arIF+02Ip/iWJQXH1hkqMkOlFWnaHndEfhBxowmTO4lzP4rW5uNLpedaMhlvpBl4Z7pMCP72w30wEy28XyNyDGlSfDyTiFqyO4TQOkq/DPiDcpyZvDFRAN+XQb3LYnJuafBYVB0BoHH4F8WY6mX0LzIXknvxNvmSoNpuWyrdZXb58SjRs0YR5FPtjf2pJHsJnpf8L/E0O0RL+PUX+FwAA//9QSwcIvI9b2aIJAACrDAAAUEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wdWIUx8kSc0gAAOBX+e9qyhKiHf6qaU1siUiCJG6WTtC2aDSefmqOH6XlPyNN/0AIoX7w9xSJWy6Z/9OAN6hDCBG8Gb7qZwido99WRidnMPcu88vl/pVa+0LJZ+arWJXJQ22XMucX4YCCErtpIY6wmhWBU64McIm3jXVbtUwLSsUdwGI0tj+DteoBJEa71NVPINaErcQMx8MR7FLSG2/dGIjInGI5gdeqJxv1quBST/zKD195fQapuyacTySucSeuOQoyvKp6TsFyRuW906whvffPXfOu0iLctbf/Am5Eqw9zjzluXu+XI/IOQ/WASj/aEP8qcATK4XtR4cx/5PJw5mkzAxy+HzoX095hTmg47wpnFN5rTpO1ousv/AP16Lodm3o5KEH38RoDfLhuB+7YKw455bJkP4kWyKgzyJm+6A8NXi/H/fx5OqIcu2l40AKG1e+vCDs68otlfyZ3jnrkqcRMTvotkK3RrfOlf6LSVSXDdDyUnw7cTW4HIFBTO9MElu17M7J1xobKbpwDeVxgEgGyHG3pfmI+Bui2CpdD+fiZE0S636hS/6X4qInZarTlZqlp+rgagq3pU5PI7K7kwlX/KYq+3lPPErOe8GA6kXyqueNcZnahR7q9zlL3VBhJilBViGkmD3Q2W9W2P9UzbpM8V+crhDGruhMXqTgUuqLO3ssub16scGm3g7a7VM8wFjcpKNzIqqwRsZuW3ZZUjnESqna+ogv7hSwvl1/tc3i16zqMJq/XInJ9mcLOcgi6nbPY379/Cjw0/Sb+m85T/21m/F8AAAD//1BLBwjgjOdEVwIAAOUCAABQSwECFAAUAAgACAAAAAAAvI9b2aIJAACrDAAALwAAAAAAAAAAAAAAAAAAAAAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wZW1QSwECFAAUAAgACAAAAAAA4IznRFcCAADlAgAALwAAAAAAAAAAAAAAAAD/CQAAaWRfcnNhXzhlOWEwNzA3LTAyZWMtNDgzZC1hYmI3LTFjNDVkMTk5YzExNi5wdWJQSwUGAAAAAAIAAgC6AAAAswwAAAAA","content_base64sha256":"Q5kZRm04HuQYtQ/cU2H8oz9IOJzhJ1l7m31cvPyEd8Q=","content_base64sha512":"ubkgmay6pwDlkJfhTB/qdZb9ges5ZjN3qCe8NnCxcl7zCHPoindvqZY67ORIuteHWQPQkTnM1KhJJeg1ZgsS2Q==","content_md5":"e1e587a1eacf0fbc2b54c17d6c5264a4","content_sha1":"323cb9d982aefd49ea4d0a75e1acf9b44d53142c","content_sha256":"439919466d381ee418b50fdc5361fca33f48389ce127597b9b7d5cbcfc8477c4","content_sha512":"b9b92099acbaa700e59097e14c1fea7596fd81eb39663377a827bc3670b1725ef30873e88a776fa9963aece448bad7875903d09139ccd4a84925e835660b12d9","directory_permission":"0700","file_permission":"0700","filename":"out/key1/id_rsa_8e9a0707-02ec-483d-abb7-1c45d199c116.zip","id":"323cb9d982aefd49ea4d0a75e1acf9b44d53142c","source":null},"sensitive_attributes":[[{"type":"get_attr","value":"content"}],[{"type":"get_attr","value":"content_base64"}]],"dependencies":["module.ssh.autoglue_ssh_key.this","module.ssh.data.http.download","module.ssh.null_resource.mkdirs"]}]},{"module":"module.ssh[\"key1\"]","mode":"managed","type":"null_resource","name":"mkdirs","provider":"provider[\"registry.opentofu.org/hashicorp/null\"]","instances":[{"index_key":0,"schema_version":0,"attributes":{"id":"1448153292650130154","triggers":null},"sensitive_attributes":[]}]},{"module":"module.ssh[\"key2\"]","mode":"data","type":"http","name":"download","provider":"provider[\"registry.opentofu.org/hashicorp/http\"]","instances":[{"index_key":0,"schema_version":0,"attributes":{"body":"{\"id\":\"44803472-4c2e-433f-a05d-38b1bbfb1e24\",\"name\":\"CI deploy key 2\",\"fingerprint\":\"SHA256:bjV3SJznTf1PWIH8D31HyFFxy4Znk1+rz4X25a02iWg\",\"zip_base64\":\"UEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzQ0ODAzNDcyLTRjMmUtNDMzZi1hMDVkLTM4YjFiYmZiMWUyNC5wZW3SBQEnV3dPP4WAIM8wxxBXBW/XSLAol6+zibNjoGO5U2Cki7dRWLmTs6erp7NpgX6ltmWxqYerc2Z2UJSrYUVYcnKOSVGGd2KJmaVJRap2oktmjlGOizYX2BhXPxdMowEBAAD//1BLBwiA5PrAZQAAAHcAAABQSwMEFAAIAAgAAAAAAAAAAAAAAAAAAAAAAC8AAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnB1YiouztBNTTEyNTW0VHB0dHR0NvarSnQ2zIly8TT0C3E1BYl5ugf7BFWEp1SYRZkk+pXme5m7u+eWZWXmFBcm+Zgn5/iEpRRFJOZFBhZVFimkpBbk5FcaOSSWluSn55SmAgIAAP//UEsHCMVvvVxlAAAAYQAAAFBLAQIUABQACAAIAAAAAACA5PrAZQAAAHcAAAAvAAAAAAAAAAAAAAAAAAAAAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnBlbVBLAQIUABQACAAIAAAAAADFb71cZQAAAGEAAAAvAAAAAAAAAAAAAAAAAMIAAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnB1YlBLBQYAAAAAAgACALoAAACEAQAAAAA=\",\"filenames\":[\"id_rsa_44803472-4c2e-433f-a05d-38b1bbfb1e24.zip\",\"id_rsa_44803472-4c2e-433f-a05d-38b1bbfb1e24.pem\",\"id_rsa_44803472-4c2e-433f-a05d-38b1bbfb1e24.pub\"]}\n","ca_cert_pem":null,"client_cert_pem":null,"client_key_pem":null,"id":"http://localhost:8080/api/v1/ssh/44803472-4c2e-433f-a05d-38b1bbfb1e24/download?part=both\u0026mode=json","insecure":null,"method":null,"request_body":null,"request_headers":{"Accept":"application/json","X-ORG-KEY":"org_lnJwmyyWH7JC-JgZo5v3Kw","X-ORG-SECRET":"fqd9yebGMfK6h5HSgWn4sXrwr9xlFbvbIYtNylRElMQ"},"request_timeout_ms":null,"response_body":"{\"id\":\"44803472-4c2e-433f-a05d-38b1bbfb1e24\",\"name\":\"CI deploy key 2\",\"fingerprint\":\"SHA256:bjV3SJznTf1PWIH8D31HyFFxy4Znk1+rz4X25a02iWg\",\"zip_base64\":\"UEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzQ0ODAzNDcyLTRjMmUtNDMzZi1hMDVkLTM4YjFiYmZiMWUyNC5wZW3SBQEnV3dPP4WAIM8wxxBXBW/XSLAol6+zibNjoGO5U2Cki7dRWLmTs6erp7NpgX6ltmWxqYerc2Z2UJSrYUVYcnKOSVGGd2KJmaVJRap2oktmjlGOizYX2BhXPxdMowEBAAD//1BLBwiA5PrAZQAAAHcAAABQSwMEFAAIAAgAAAAAAAAAAAAAAAAAAAAAAC8AAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnB1YiouztBNTTEyNTW0VHB0dHR0NvarSnQ2zIly8TT0C3E1BYl5ugf7BFWEp1SYRZkk+pXme5m7u+eWZWXmFBcm+Zgn5/iEpRRFJOZFBhZVFimkpBbk5FcaOSSWluSn55SmAgIAAP//UEsHCMVvvVxlAAAAYQAAAFBLAQIUABQACAAIAAAAAACA5PrAZQAAAHcAAAAvAAAAAAAAAAAAAAAAAAAAAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnBlbVBLAQIUABQACAAIAAAAAADFb71cZQAAAGEAAAAvAAAAAAAAAAAAAAAAAMIAAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnB1YlBLBQYAAAAAAgACALoAAACEAQAAAAA=\",\"filenames\":[\"id_rsa_44803472-4c2e-433f-a05d-38b1bbfb1e24.zip\",\"id_rsa_44803472-4c2e-433f-a05d-38b1bbfb1e24.pem\",\"id_rsa_44803472-4c2e-433f-a05d-38b1bbfb1e24.pub\"]}\n","response_body_base64":"eyJpZCI6IjQ0ODAzNDcyLTRjMmUtNDMzZi1hMDVkLTM4YjFiYmZiMWUyNCIsIm5hbWUiOiJDSSBkZXBsb3kga2V5IDIiLCJmaW5nZXJwcmludCI6IlNIQTI1NjpialYzU0p6blRmMVBXSUg4RDMxSHlGRnh5NFpuazErcno0WDI1YTAyaVdnIiwiemlwX2Jhc2U2NCI6IlVFc0RCQlFBQ0FBSUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBdkFBQUFhV1JmY25OaFh6UTBPREF6TkRjeUxUUmpNbVV0TkRNelppMWhNRFZrTFRNNFlqRmlZbVppTVdVeU5DNXdaVzNTQlFFblYzZFBQNFdBSU04d3h4QlhCVy9YU0xBb2w2K3ppYk5qb0dPNVUyQ2tpN2RSV0xtVHM2ZXJwN05wZ1g2bHRtV3hxWWVyYzJaMlVKU3JZVVZZY25LT1NWR0dkMktKbWFWSlJhcDJva3RtamxHT2l6WVgyQmhYUHhkTW93RUJBQUQvLzFCTEJ3aUE1UHJBWlFBQUFIY0FBQUJRU3dNRUZBQUlBQWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQzhBQUFCcFpGOXljMkZmTkRRNE1ETTBOekl0TkdNeVpTMDBNek5tTFdFd05XUXRNemhpTVdKaVptSXhaVEkwTG5CMVlpb3V6dEJOVFRFeU5UVzBWSEIwZEhSME52YXJTblEyeklseThUVDBDM0UxQllsNXVnZjdCRldFcDFTWVJaa2srcFhtZTVtN3UrZVdaV1htRkJjbStaZ241L2lFcFJSRkpPWkZCaFpWRmlta3BCYms1RmNhT1NTV2x1U241NVNtQWdJQUFQLy9VRXNIQ01WdnZWeGxBQUFBWVFBQUFGQkxBUUlVQUJRQUNBQUlBQUFBQUFDQTVQckFaUUFBQUhjQUFBQXZBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQnBaRjl5YzJGZk5EUTRNRE0wTnpJdE5HTXlaUzAwTXpObUxXRXdOV1F0TXpoaU1XSmlabUl4WlRJMExuQmxiVkJMQVFJVUFCUUFDQUFJQUFBQUFBREZiNzFjWlFBQUFHRUFBQUF2QUFBQUFBQUFBQUFBQUFBQUFNSUFBQUJwWkY5eWMyRmZORFE0TURNME56SXROR015WlMwME16Tm1MV0V3TldRdE16aGlNV0ppWm1JeFpUSTBMbkIxWWxCTEJRWUFBQUFBQWdBQ0FMb0FBQUNFQVFBQUFBQT0iLCJmaWxlbmFtZXMiOlsiaWRfcnNhXzQ0ODAzNDcyLTRjMmUtNDMzZi1hMDVkLTM4YjFiYmZiMWUyNC56aXAiLCJpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnBlbSIsImlkX3JzYV80NDgwMzQ3Mi00YzJlLTQzM2YtYTA1ZC0zOGIxYmJmYjFlMjQucHViIl19Cg==","response_headers":{"Content-Length":"1114","Content-Security-Policy":"default-src 'self'; base-uri 'self'; form-action 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' http://localhost:5173; style-src 'self' 'unsafe-inline' http://localhost:5173 https://fonts.googleapis.com; img-src 'self' data: blob:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' http://localhost:5173 ws://localhost:5173 ws://localhost:8080; frame-ancestors 'none'","Content-Type":"application/json","Date":"Sat, 01 Nov 2025 07:04:38 GMT","Permissions-Policy":"geolocation=(), camera=(), microphone=(), interest-cohort=()","Referrer-Policy":"strict-origin-when-cross-origin","Vary":"Origin","X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","X-Ratelimit-Limit":"100","X-Ratelimit-Remaining":"97","X-Ratelimit-Reset":"1761980700"},"retry":null,"status_code":200,"url":"http://localhost:8080/api/v1/ssh/44803472-4c2e-433f-a05d-38b1bbfb1e24/download?part=both\u0026mode=json"},"sensitive_attributes":[[{"type":"get_attr","value":"request_headers"},{"type":"index","value":{"value":"X-ORG-KEY","type":"string"}}],[{"type":"get_attr","value":"request_headers"},{"type":"index","value":{"value":"X-ORG-SECRET","type":"string"}}]]}]},{"module":"module.ssh[\"key2\"]","mode":"managed","type":"autoglue_ssh_key","name":"this","provider":"provider[\"glueops/autoglue/autoglue\"]","instances":[{"schema_version":0,"attributes":{"bits":null,"comment":"deploy2@autoglue","created_at":"2025-11-01T07:04:38Z","fingerprint":"SHA256:bjV3SJznTf1PWIH8D31HyFFxy4Znk1+rz4X25a02iWg","id":"44803472-4c2e-433f-a05d-38b1bbfb1e24","name":"CI deploy key 2","private_key_pem":null,"public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGSLRxWdx6Z4aNuoJ7GGmvjilsqbL7clLVdrXanYQryr deploy2@autoglue","type":"ed25519","updated_at":"2025-11-01T07:04:38Z"},"sensitive_attributes":[[{"type":"get_attr","value":"private_key_pem"}]]}]},{"module":"module.ssh[\"key2\"]","mode":"managed","type":"local_sensitive_file","name":"zip","provider":"provider[\"registry.opentofu.org/hashicorp/local\"]","instances":[{"index_key":0,"schema_version":0,"attributes":{"content":null,"content_base64":"UEsDBBQACAAIAAAAAAAAAAAAAAAAAAAAAAAvAAAAaWRfcnNhXzQ0ODAzNDcyLTRjMmUtNDMzZi1hMDVkLTM4YjFiYmZiMWUyNC5wZW3SBQEnV3dPP4WAIM8wxxBXBW/XSLAol6+zibNjoGO5U2Cki7dRWLmTs6erp7NpgX6ltmWxqYerc2Z2UJSrYUVYcnKOSVGGd2KJmaVJRap2oktmjlGOizYX2BhXPxdMowEBAAD//1BLBwiA5PrAZQAAAHcAAABQSwMEFAAIAAgAAAAAAAAAAAAAAAAAAAAAAC8AAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnB1YiouztBNTTEyNTW0VHB0dHR0NvarSnQ2zIly8TT0C3E1BYl5ugf7BFWEp1SYRZkk+pXme5m7u+eWZWXmFBcm+Zgn5/iEpRRFJOZFBhZVFimkpBbk5FcaOSSWluSn55SmAgIAAP//UEsHCMVvvVxlAAAAYQAAAFBLAQIUABQACAAIAAAAAACA5PrAZQAAAHcAAAAvAAAAAAAAAAAAAAAAAAAAAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnBlbVBLAQIUABQACAAIAAAAAADFb71cZQAAAGEAAAAvAAAAAAAAAAAAAAAAAMIAAABpZF9yc2FfNDQ4MDM0NzItNGMyZS00MzNmLWEwNWQtMzhiMWJiZmIxZTI0LnB1YlBLBQYAAAAAAgACALoAAACEAQAAAAA=","content_base64sha256":"ZRPiFqb0a5WdSSb+coKbsQKnLZJRnS+a54zTRj9JnuE=","content_base64sha512":"/Zih3xdtPz8/s7/1o3Q+i2YPSwRaRYKeJS1SDSdm/yQ45Tn91aJgsLC7RemQl2wDt9pcvcCa/qJFPZ1KT4vYSw==","content_md5":"602d52ba829b8fb9f09dad071d48ed0c","content_sha1":"2dc8e325dd54881040524fdc98a233a329ea5a77","content_sha256":"6513e216a6f46b959d4926fe72829bb102a72d92519d2f9ae78cd3463f499ee1","content_sha512":"fd98a1df176d3f3f3fb3bff5a3743e8b660f4b045a45829e252d520d2766ff2438e539fdd5a260b0b0bb45e990976c03b7da5cbdc09afea2453d9d4a4f8bd84b","directory_permission":"0700","file_permission":"0700","filename":"out/key2/id_rsa_44803472-4c2e-433f-a05d-38b1bbfb1e24.zip","id":"2dc8e325dd54881040524fdc98a233a329ea5a77","source":null},"sensitive_attributes":[[{"type":"get_attr","value":"content"}],[{"type":"get_attr","value":"content_base64"}]],"dependencies":["module.ssh.autoglue_ssh_key.this","module.ssh.data.http.download","module.ssh.null_resource.mkdirs"]}]},{"module":"module.ssh[\"key2\"]","mode":"managed","type":"null_resource","name":"mkdirs","provider":"provider[\"registry.opentofu.org/hashicorp/null\"]","instances":[{"index_key":0,"schema_version":0,"attributes":{"id":"6741240159027812521","triggers":null},"sensitive_attributes":[]}]}],"check_results":[{"object_kind":"resource","config_addr":"module.ssh.local_sensitive_file.zip","status":"pass","objects":[{"object_addr":"module.ssh[\"key2\"].local_sensitive_file.zip[0]","status":"pass"},{"object_addr":"module.ssh[\"key1\"].local_sensitive_file.zip[0]","status":"pass"}]}]} diff --git a/terraform/envs/dev/terraform.tfvars b/terraform/envs/dev/terraform.tfvars new file mode 100644 index 0000000..27278bd --- /dev/null +++ b/terraform/envs/dev/terraform.tfvars @@ -0,0 +1,23 @@ +org_key = "org_lnJwmyyWH7JC-JgZo5v3Kw" +org_secret = "fqd9yebGMfK6h5HSgWn4sXrwr9xlFbvbIYtNylRElMQ" + +ssh_keys = { + key1 = { + name = "CI deploy key 1" + comment = "deploy1@autoglue" + type = "rsa" + bits = 4096 + enable_download = true + download_part = "both" + download_dir = "out/key1" + } + key2 = { + name = "CI deploy key 2" + comment = "deploy2@autoglue" + type = "ed25519" # bits ignored + enable_download = true + download_part = "both" + download_dir = "out/key2" + } +} + diff --git a/terraform/envs/dev/variables.tf b/terraform/envs/dev/variables.tf new file mode 100644 index 0000000..b475b21 --- /dev/null +++ b/terraform/envs/dev/variables.tf @@ -0,0 +1,30 @@ +variable "addr" { + description = "Base URL to the Autoglue API, e.g. http://localhost:8080/api/v1" + type = string + default = "http://localhost:8080/api/v1" +} + +variable "org_key" { + description = "Org key for machine auth (sent as X-ORG-KEY)" + type = string + sensitive = true +} + +variable "org_secret" { + description = "Org secret for machine auth (sent as X-ORG-SECRET)" + type = string + sensitive = true +} + +variable "ssh_keys" { + description = "Map of SSH key specs" + type = map(object({ + name = string + comment = string + type = string + bits = optional(number) + enable_download = optional(bool, true) + download_part = optional(string, "both") + download_dir = optional(string, "out") + })) +} diff --git a/terraform/envs/dev/versions.tf b/terraform/envs/dev/versions.tf new file mode 100644 index 0000000..988d663 --- /dev/null +++ b/terraform/envs/dev/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.5.0" + + required_providers { + autoglue = { + source = "glueops/autoglue/autoglue" + version = "0.0.1" # matches your dev install VER + } + http = { + source = "hashicorp/http" + version = ">= 3.4.0" + } + local = { + source = "hashicorp/local" + version = ">= 2.5.1" + } + } +} \ No newline at end of file diff --git a/terraform/modules/ssh-key/main.tf b/terraform/modules/ssh-key/main.tf new file mode 100644 index 0000000..c217168 --- /dev/null +++ b/terraform/modules/ssh-key/main.tf @@ -0,0 +1,68 @@ +locals { is_rsa = var.type == "rsa" } + +# 1) Create key +resource "autoglue_ssh_key" "this" { + name = var.name + comment = var.comment + type = var.type + bits = local.is_rsa ? var.bits : null +} + +# 2) Optionally download via HTTP (mode=json) +data "http" "download" { + count = var.enable_download ? 1 : 0 + + url = "${var.addr}/ssh/${autoglue_ssh_key.this.id}/download?part=${var.download_part}&mode=json" + + # Inherit org_key/org_secret via provider headers — we’re not configuring http headers here + # because your API auth for downloads is via X-ORG-KEY / X-ORG-SECRET. + # If you require those headers here, add request_headers and pass them from root as inputs. + # For org key/secret auth on download, uncomment and add module inputs: + request_headers = { + "X-ORG-KEY" = var.org_key + "X-ORG-SECRET" = var.org_secret + "Accept" = "application/json" + } +} + +locals { + dl = var.enable_download ? jsondecode(one(data.http.download[*].response_body)) : null + zip_b64 = coalesce(try(local.dl.zipBase64, null), try(local.dl.zip_base64, null)) +} + +resource "null_resource" "mkdirs" { + count = var.enable_download ? 1 : 0 + provisioner "local-exec" { command = "mkdir -p ${var.download_dir}" } +} + +# public only +resource "local_file" "public_key" { + count = var.enable_download && var.download_part == "public" ? 1 : 0 + filename = "${var.download_dir}/${try(local.dl.filenames[0], "id_rsa.pub")}" + content = try(local.dl.publicKey, "") + file_permission = "0644" + depends_on = [null_resource.mkdirs] +} + +# private only +resource "local_sensitive_file" "private_key" { + count = var.enable_download && var.download_part == "private" ? 1 : 0 + filename = "${var.download_dir}/${try(local.dl.filenames[0], "id_rsa.pem")}" + content = try(local.dl.privatePEM, "") + depends_on = [null_resource.mkdirs] +} + +# both -> zip +resource "local_sensitive_file" "zip" { + count = var.enable_download && var.download_part == "both" ? 1 : 0 + filename = "${var.download_dir}/${try(local.dl.filenames[0], "ssh_key.zip")}" + content_base64 = local.zip_b64 + depends_on = [null_resource.mkdirs] + + lifecycle { + postcondition { + condition = length(try(local.zip_b64, "")) > 0 + error_message = "API did not return a zip payload for part=both." + } + } +} diff --git a/terraform/modules/ssh-key/outputs.tf b/terraform/modules/ssh-key/outputs.tf new file mode 100644 index 0000000..04f2959 --- /dev/null +++ b/terraform/modules/ssh-key/outputs.tf @@ -0,0 +1,12 @@ +output "id" { value = autoglue_ssh_key.this.id } +output "public_key" { value = autoglue_ssh_key.this.public_key } +output "fingerprint" { value = autoglue_ssh_key.this.fingerprint } +output "created_at" { value = autoglue_ssh_key.this.created_at } + +output "written_files" { + value = compact(concat( + var.enable_download && var.download_part == "public" ? [local_file.public_key[0].filename] : [], + var.enable_download && var.download_part == "private" ? [local_sensitive_file.private_key[0].filename] : [], + var.enable_download && var.download_part == "both" ? [local_sensitive_file.zip[0].filename] : [] + )) +} diff --git a/terraform/modules/ssh-key/variables.tf b/terraform/modules/ssh-key/variables.tf new file mode 100644 index 0000000..e68476d --- /dev/null +++ b/terraform/modules/ssh-key/variables.tf @@ -0,0 +1,47 @@ +variable "addr" { + type = string +} + +variable "org_key" { + type = string + sensitive = true + default = null +} + +variable "org_secret" { + type = string + sensitive = true + default = null +} + +variable "name" { + type = string +} + +variable "comment" { + type = string +} + +variable "type" { + type = string +} + +variable "enable_download" { + type = bool + default = false +} + +variable "download_part" { + type = string + default = "both" +} + +variable "download_dir" { + type = string + default = "ssh_artifacts" +} + +variable "bits" { + type = number + default = null # null for ed25519 +} \ No newline at end of file diff --git a/terraform/modules/ssh-key/versions.tf b/terraform/modules/ssh-key/versions.tf new file mode 100644 index 0000000..14632db --- /dev/null +++ b/terraform/modules/ssh-key/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.5.0" + + required_providers { + autoglue = { + source = "glueops/autoglue/autoglue" + } + http = { + source = "hashicorp/http" + } + local = { + source = "hashicorp/local" + } + null = { + source = "hashicorp/null" + } + } +} diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/ui/.prettierignore b/ui/.prettierignore new file mode 100644 index 0000000..916f419 --- /dev/null +++ b/ui/.prettierignore @@ -0,0 +1 @@ +src/sdk \ No newline at end of file diff --git a/ui/.prettierrc.json b/ui/.prettierrc.json new file mode 100644 index 0000000..74ca29e --- /dev/null +++ b/ui/.prettierrc.json @@ -0,0 +1,37 @@ +{ + "endOfLine": "lf", + "semi": false, + "singleQuote": false, + "tabWidth": 2, + "printWidth": 100, + "trailingComma": "es5", + "importOrder": [ + "^(react/(.*)$)|^(react$)", + "^(next/(.*)$)|^(next$)", + "", + "", + "^@workspace/(.*)$", + "", + "^types$", + "^@/types/(.*)$", + "^@/config/(.*)$", + "^@/lib/(.*)$", + "^@/hooks/(.*)$", + "^@/components/ui/(.*)$", + "^@/components/(.*)$", + "^@/pages/(.*)$", + "^@/registry/(.*)$", + "^@/styles/(.*)$", + "^@/app/(.*)$", + "^@/www/(.*)$", + "", + "^[./]" + ], + "importOrderSeparation": false, + "importOrderSortSpecifiers": true, + "importOrderBuiltinModulesToTop": true, + "importOrderParserPlugins": ["typescript", "jsx", "decorators-legacy"], + "importOrderMergeDuplicateImports": true, + "importOrderCombineTypeAndValueImports": true, + "plugins": ["@ianvs/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"] +} diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 0000000..d2e7761 --- /dev/null +++ b/ui/README.md @@ -0,0 +1,73 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` diff --git a/ui/components.json b/ui/components.json new file mode 100644 index 0000000..2357e03 --- /dev/null +++ b/ui/components.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/index.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "registries": {} +} diff --git a/ui/eslint.config.js b/ui/eslint.config.js new file mode 100644 index 0000000..b19330b --- /dev/null +++ b/ui/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/ui/index.html b/ui/index.html new file mode 100644 index 0000000..51a1bfa --- /dev/null +++ b/ui/index.html @@ -0,0 +1,13 @@ + + + + + + + AutoGlue + + +
+ + + diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..6099e9d --- /dev/null +++ b/ui/package.json @@ -0,0 +1,85 @@ +{ + "name": "ui", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@hookform/resolvers": "^5.2.2", + "@radix-ui/react-accordion": "^1.2.12", + "@radix-ui/react-alert-dialog": "^1.1.15", + "@radix-ui/react-aspect-ratio": "^1.1.7", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-collapsible": "^1.1.12", + "@radix-ui/react-context-menu": "^2.2.16", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-hover-card": "^1.1.15", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-menubar": "^1.1.16", + "@radix-ui/react-navigation-menu": "^1.2.14", + "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-radio-group": "^1.3.8", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-select": "^2.2.6", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slider": "^1.3.6", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-toggle": "^1.1.10", + "@radix-ui/react-toggle-group": "^1.1.11", + "@radix-ui/react-tooltip": "^1.2.8", + "@tailwindcss/vite": "^4.1.16", + "@tanstack/react-query": "^5.90.5", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "cmdk": "^1.1.1", + "date-fns": "^4.1.0", + "embla-carousel-react": "^8.6.0", + "input-otp": "^1.4.2", + "lucide-react": "^0.548.0", + "next-themes": "^0.4.6", + "react": "^19.2.0", + "react-day-picker": "^9.11.1", + "react-dom": "^19.2.0", + "react-hook-form": "^7.65.0", + "react-icons": "^5.5.0", + "react-resizable-panels": "^3.0.6", + "react-router-dom": "^7.9.5", + "recharts": "2.15.4", + "sonner": "^2.0.7", + "tailwind-merge": "^3.3.1", + "tailwindcss": "^4.1.16", + "vaul": "^1.1.2", + "zod": "^4.1.12" + }, + "devDependencies": { + "@eslint/js": "^9.38.0", + "@ianvs/prettier-plugin-sort-imports": "^4.7.0", + "@types/node": "^24.9.2", + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.2", + "@vitejs/plugin-react": "^5.1.0", + "eslint": "^9.38.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.4", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.4.24", + "globals": "^16.4.0", + "prettier": "^3.6.2", + "prettier-plugin-tailwindcss": "^0.7.1", + "shadcn": "^3.5.0", + "tw-animate-css": "^1.4.0", + "typescript": "~5.9.3", + "typescript-eslint": "^8.46.2", + "vite": "^7.1.12" + } +} diff --git a/ui/public/vite.svg b/ui/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/ui/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/src/App.tsx b/ui/src/App.tsx new file mode 100644 index 0000000..1e551ed --- /dev/null +++ b/ui/src/App.tsx @@ -0,0 +1,34 @@ +import { AppShell } from "@/layouts/app-shell.tsx" +import { Route, Routes } from "react-router-dom" + +import { ProtectedRoute } from "@/components/protected-route.tsx" +import { Login } from "@/pages/auth/login.tsx" +import { MePage } from "@/pages/me/me-page.tsx" +import { OrgApiKeys } from "@/pages/org/api-keys.tsx" +import { OrgMembers } from "@/pages/org/members.tsx" +import { OrgSettings } from "@/pages/org/settings.tsx" +import { ServerPage } from "@/pages/servers/server-page.tsx" +import { SshPage } from "@/pages/ssh/ssh-page.tsx" +import { TaintsPage } from "@/pages/taints/taints-page.tsx" + +export default function App() { + return ( + + } /> + }> + }> + } /> + + } /> + } /> + } /> + + } /> + } /> + } /> + + + } /> + + ) +} diff --git a/ui/src/api/me.ts b/ui/src/api/me.ts new file mode 100644 index 0000000..c9930c3 --- /dev/null +++ b/ui/src/api/me.ts @@ -0,0 +1,40 @@ +import { withRefresh } from "@/api/with-refresh.ts" +import type { + HandlersCreateUserKeyRequest, + HandlersMeResponse, + HandlersUpdateMeRequest, + HandlersUserAPIKeyOut, + ModelsUser, +} from "@/sdk" +import { makeMeApi, makeMeKeysApi } from "@/sdkClient.ts" + +const me = makeMeApi() +const keys = makeMeKeysApi() + +export const meApi = { + getMe: () => + withRefresh(async (): Promise => { + return await me.getMe() + }), + + updateMe: (body: HandlersUpdateMeRequest) => + withRefresh(async (): Promise => { + return await me.updateMe({ body }) + }), + + listKeys: () => + withRefresh(async (): Promise => { + return await keys.listUserAPIKeys() + }), + + createKey: (body: HandlersCreateUserKeyRequest) => + withRefresh(async (): Promise => { + return await keys.createUserAPIKey({ body }) + }), + + deleteKey: (id: string) => + withRefresh(async (): Promise => { + await keys.deleteUserAPIKey({ id }) + return true + }), +} diff --git a/ui/src/api/servers.ts b/ui/src/api/servers.ts new file mode 100644 index 0000000..4f1cf59 --- /dev/null +++ b/ui/src/api/servers.ts @@ -0,0 +1,28 @@ +import { withRefresh } from "@/api/with-refresh.ts" +import type { DtoCreateServerRequest, DtoUpdateServerRequest } from "@/sdk" +import { makeServersApi } from "@/sdkClient.ts" + +const servers = makeServersApi() + +export const serversApi = { + listServers: () => + withRefresh(async () => { + return await servers.listServers() + }), + createServer: (body: DtoCreateServerRequest) => + withRefresh(async () => { + return await servers.createServer({ body }) + }), + getServer: (id: string) => + withRefresh(async () => { + return await servers.getServer({ id }) + }), + updateServer: (id: string, body: DtoUpdateServerRequest) => + withRefresh(async () => { + return await servers.updateServer({ id, body }) + }), + deleteServer: (id: string) => + withRefresh(async () => { + await servers.deleteServer({ id }) + }), +} diff --git a/ui/src/api/ssh.ts b/ui/src/api/ssh.ts new file mode 100644 index 0000000..1523d03 --- /dev/null +++ b/ui/src/api/ssh.ts @@ -0,0 +1,75 @@ +import { withRefresh } from "@/api/with-refresh.ts" +import type { DtoCreateSSHRequest, DtoSshResponse, DtoSshRevealResponse } from "@/sdk" +import { makeSshApi } from "@/sdkClient.ts" + +const ssh = makeSshApi() +export type SshDownloadPart = "public" | "private" | "both" + +export const sshApi = { + listSshKeys: () => + withRefresh(async (): Promise => { + return await ssh.listPublicSshKeys() + }), + + createSshKey: (body: DtoCreateSSHRequest) => + withRefresh(async (): Promise => { + // SDK expects { body } + return await ssh.createSSHKey({ body }) + }), + + getSshKeyById: (id: string) => + withRefresh(async (): Promise => { + return await ssh.getSSHKey({ id }) + }), + + revealSshKeyById: (id: string) => + withRefresh(async (): Promise => { + return await ssh.getSSHKey({ id, reveal: true as any }) + // Note: TS fetch generator often models query params as part of params bag. + // If your generated client uses a different shape, change to: + // return await ssh.getSSHKeyRaw({ id, reveal: true }).then(r => r.value()) + }), + + deleteSshKey: (id: string) => + withRefresh(async (): Promise => { + await ssh.deleteSSHKey({ id }) + }), + + // 1) JSON mode: returns structured JSON with filenames & (optionally) base64 zip + downloadJson: (id: string, part: SshDownloadPart) => + withRefresh(async () => { + const url = new URL(`/api/v1/ssh/${id}/download`, window.location.origin) + url.searchParams.set("part", part) + url.searchParams.set("mode", "json") + + const res = await fetch(url.toString()) + if (!res.ok) throw new Error(`Download failed: ${res.statusText}`) + return (await res.json()) as { + id: string + name: string | null + fingerprint: string + filenames: string[] + publicKey?: string | null + privatePEM?: string | null + zipBase64?: string | null + } + }), + + // 2) Attachment mode: returns a Blob (public/private file or a .zip) + downloadBlob: (id: string, part: SshDownloadPart) => + withRefresh(async (): Promise<{ filename: string; blob: Blob }> => { + const url = new URL(`/api/v1/ssh/${id}/download`, window.location.origin) + url.searchParams.set("part", part) + + const res = await fetch(url.toString()) + if (!res.ok) throw new Error(`Download failed: ${res.statusText}`) + + // Parse filename from Content-Disposition + const cd = res.headers.get("Content-Disposition") || "" + const match = /filename="([^"]+)"/i.exec(cd) + const filename = match?.[1] ?? "ssh-key-download" + + const blob = await res.blob() + return { filename, blob } + }), +} diff --git a/ui/src/api/taints.ts b/ui/src/api/taints.ts new file mode 100644 index 0000000..9713839 --- /dev/null +++ b/ui/src/api/taints.ts @@ -0,0 +1,23 @@ +import { withRefresh } from "@/api/with-refresh.ts" +import type { DtoCreateTaintRequest, DtoUpdateTaintRequest } from "@/sdk" +import { makeTaintsApi } from "@/sdkClient.ts" + +const taints = makeTaintsApi() +export const taintsApi = { + listTaints: () => + withRefresh(async () => { + return await taints.listTaints() + }), + createTaint: (body: DtoCreateTaintRequest) => + withRefresh(async () => { + return await taints.createTaint({ body }) + }), + deleteTaint: (id: string) => + withRefresh(async () => { + await taints.deleteTaint({ id }) + }), + updateTaint: (id: string, body: DtoUpdateTaintRequest) => + withRefresh(async () => { + return await taints.updateTaint({ id, body }) + }), +} diff --git a/ui/src/api/with-refresh.ts b/ui/src/api/with-refresh.ts new file mode 100644 index 0000000..b9cd7f4 --- /dev/null +++ b/ui/src/api/with-refresh.ts @@ -0,0 +1,62 @@ +// api/with-refresh.ts +import { authStore, type TokenPair } from "@/auth/store.ts" +import { API_BASE } from "@/sdkClient.ts" + +let inflightRefresh: Promise | null = null + +async function doRefresh(): Promise { + const tokens = authStore.get() + if (!tokens?.refresh_token) return false + + try { + const res = await fetch(`${API_BASE}/auth/refresh`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ refresh_token: tokens.refresh_token }), + }) + + if (!res.ok) return false + + const next = (await res.json()) as TokenPair + authStore.set(next) + return true + } catch { + return false + } +} + +async function refreshOnce(): Promise { + if (!inflightRefresh) { + inflightRefresh = doRefresh().finally(() => { + inflightRefresh = null + }) + } + return inflightRefresh +} + +function isUnauthorized(err: any): boolean { + return ( + err?.status === 401 || + err?.cause?.status === 401 || + err?.response?.status === 401 || + (err instanceof Response && err.status === 401) + ) +} + +export async function withRefresh(fn: () => Promise): Promise { + // Optional: attempt a proactive refresh if close to expiry + if (authStore.willExpireSoon?.(30)) { + await refreshOnce() + } + + try { + return await fn() + } catch (error) { + if (!isUnauthorized(error)) throw error + + const ok = await refreshOnce() + if (!ok) throw error + + return await fn() + } +} diff --git a/ui/src/auth/org.ts b/ui/src/auth/org.ts new file mode 100644 index 0000000..57557fb --- /dev/null +++ b/ui/src/auth/org.ts @@ -0,0 +1,29 @@ +const KEY = "autoglue.org" + +let cache: string | null = localStorage.getItem(KEY) + +export const orgStore = { + get(): string | null { + return cache + }, + set(id: string) { + cache = id + localStorage.setItem(KEY, id) + window.dispatchEvent(new CustomEvent("autoglue:org-change", { detail: id })) + }, + subscribe(fn: (id: string | null) => void) { + const onCustom = (e: Event) => fn((e as CustomEvent).detail ?? null) + const onStorage = (e: StorageEvent) => { + if (e.key === KEY) { + cache = e.newValue + fn(cache) + } + } + window.addEventListener("autoglue:org-change", onCustom as EventListener) + window.addEventListener("storage", onStorage) + return () => { + window.removeEventListener("autoglue:org-change", onCustom as EventListener) + window.removeEventListener("storage", onStorage) + } + }, +} diff --git a/ui/src/auth/store.ts b/ui/src/auth/store.ts new file mode 100644 index 0000000..1ab8744 --- /dev/null +++ b/ui/src/auth/store.ts @@ -0,0 +1,112 @@ +export type TokenPair = { + access_token: string + refresh_token: string + token_type: string + expires_in: number +} + +const KEY = "autoglue.tokens" +const EVT = "autoglue.auth-change" + +let cache: TokenPair | null = read() + +function read(): TokenPair | null { + try { + const raw = localStorage.getItem(KEY) + return raw ? (JSON.parse(raw) as TokenPair) : null + } catch { + return null + } +} + +function write(tokens: TokenPair | null) { + if (tokens) localStorage.setItem(KEY, JSON.stringify(tokens)) + else localStorage.removeItem(KEY) +} + +function emit(tokens: TokenPair | null) { + // include payload for convenience + window.dispatchEvent(new CustomEvent(EVT, { detail: tokens })) +} + +export const authStore = { + /** Current tokens (from in-memory cache). */ + get(): TokenPair | null { + return cache + }, + + /** Set tokens; updates memory, localStorage, broadcasts event. */ + set(tokens: TokenPair | null) { + cache = tokens + write(tokens) + emit(tokens) + }, + + /** Fresh read from storage (useful if you suspect out-of-band changes). */ + reload(): TokenPair | null { + cache = read() + return cache + }, + + /** Is there an access token at all? (not checking expiry) */ + isAuthed(): boolean { + return !!cache?.access_token + }, + + /** Convenience accessor */ + getAccessToken(): string | null { + return cache?.access_token ?? null + }, + + /** Decode JWT exp and check expiry (no clock skew handling here). */ + isExpired(nowSec = Math.floor(Date.now() / 1000)): boolean { + const exp = decodeExp(cache?.access_token) + return exp !== null ? nowSec >= exp : true + }, + + /** Will expire within `thresholdSec` (default 60s). */ + willExpireSoon(thresholdSec = 60, nowSec = Math.floor(Date.now() / 1000)): boolean { + const exp = decodeExp(cache?.access_token) + return exp !== null ? exp - nowSec <= thresholdSec : true + }, + + logout() { + authStore.set(null) + }, + + /** Subscribe to changes (pairs well with useSyncExternalStore). */ + subscribe(fn: (tokens: TokenPair | null) => void): () => void { + const onCustom = (e: Event) => fn((e as CustomEvent).detail ?? null) + const onStorage = (e: StorageEvent) => { + if (e.key === KEY) { + cache = read() + fn(cache) + } + } + + window.addEventListener(EVT, onCustom as EventListener) + window.addEventListener("storage", onStorage) + return () => { + window.removeEventListener(EVT, onCustom as EventListener) + window.removeEventListener("storage", onStorage) + } + }, +} + +// --- helpers --- +function decodeExp(jwt?: string): number | null { + if (!jwt) return null + const parts = jwt.split(".") + if (parts.length < 2) return null + try { + const json = JSON.parse(atob(base64urlToBase64(parts[1]))) + const exp = typeof json?.exp === "number" ? json.exp : null + return exp ?? null + } catch { + return null + } +} + +function base64urlToBase64(s: string) { + return s.replace(/-/g, "+").replace(/_/g, "/") + "==".slice((2 - ((s.length * 3) % 4)) % 4) +} diff --git a/ui/src/auth/use-auth.ts b/ui/src/auth/use-auth.ts new file mode 100644 index 0000000..8ca0a09 --- /dev/null +++ b/ui/src/auth/use-auth.ts @@ -0,0 +1,17 @@ +import { useSyncExternalStore } from "react" +import { authStore, type TokenPair } from "@/auth/store.ts" + +export const useAuth = () => { + const tokens = useSyncExternalStore( + (cb) => authStore.subscribe(cb), + () => authStore.get(), + () => authStore.get() // server snapshot (SSR) + ) + + return { + tokens, + authed: !!tokens?.access_token, + isExpired: authStore.isExpired(), + willExpireSoon: authStore.willExpireSoon(), + } +} diff --git a/ui/src/components/protected-route.tsx b/ui/src/components/protected-route.tsx new file mode 100644 index 0000000..c61b0a5 --- /dev/null +++ b/ui/src/components/protected-route.tsx @@ -0,0 +1,12 @@ +import { useAuth } from "@/auth/use-auth.ts" +import { Navigate, Outlet, useLocation } from "react-router-dom" + +export const ProtectedRoute = () => { + const { authed } = useAuth() + const loc = useLocation() + + if (!authed) { + return + } + return +} diff --git a/ui/src/components/ui/accordion.tsx b/ui/src/components/ui/accordion.tsx new file mode 100644 index 0000000..425e353 --- /dev/null +++ b/ui/src/components/ui/accordion.tsx @@ -0,0 +1,62 @@ +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDownIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Accordion({ ...props }: React.ComponentProps) { + return +} + +function AccordionItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AccordionTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + + ) +} + +function AccordionContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + +
{children}
+
+ ) +} + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/ui/src/components/ui/alert-dialog.tsx b/ui/src/components/ui/alert-dialog.tsx new file mode 100644 index 0000000..c4b8f93 --- /dev/null +++ b/ui/src/components/ui/alert-dialog.tsx @@ -0,0 +1,133 @@ +import * as React from "react" +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" + +import { cn } from "@/lib/utils" +import { buttonVariants } from "@/components/ui/button" + +function AlertDialog({ ...props }: React.ComponentProps) { + return +} + +function AlertDialogTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function AlertDialogPortal({ ...props }: React.ComponentProps) { + return +} + +function AlertDialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + + ) +} + +function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogAction({ + className, + ...props +}: React.ComponentProps) { + return +} + +function AlertDialogCancel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} diff --git a/ui/src/components/ui/alert.tsx b/ui/src/components/ui/alert.tsx new file mode 100644 index 0000000..88153ef --- /dev/null +++ b/ui/src/components/ui/alert.tsx @@ -0,0 +1,60 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const alertVariants = cva( + "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", + { + variants: { + variant: { + default: "bg-card text-card-foreground", + destructive: + "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Alert({ + className, + variant, + ...props +}: React.ComponentProps<"div"> & VariantProps) { + return ( +
+ ) +} + +function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDescription({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +export { Alert, AlertTitle, AlertDescription } diff --git a/ui/src/components/ui/aspect-ratio.tsx b/ui/src/components/ui/aspect-ratio.tsx new file mode 100644 index 0000000..a7b5855 --- /dev/null +++ b/ui/src/components/ui/aspect-ratio.tsx @@ -0,0 +1,9 @@ +"use client" + +import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" + +function AspectRatio({ ...props }: React.ComponentProps) { + return +} + +export { AspectRatio } diff --git a/ui/src/components/ui/avatar.tsx b/ui/src/components/ui/avatar.tsx new file mode 100644 index 0000000..7f0217d --- /dev/null +++ b/ui/src/components/ui/avatar.tsx @@ -0,0 +1,39 @@ +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" + +import { cn } from "@/lib/utils" + +function Avatar({ className, ...props }: React.ComponentProps) { + return ( + + ) +} + +function AvatarImage({ className, ...props }: React.ComponentProps) { + return ( + + ) +} + +function AvatarFallback({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/ui/src/components/ui/badge.tsx b/ui/src/components/ui/badge.tsx new file mode 100644 index 0000000..3350e31 --- /dev/null +++ b/ui/src/components/ui/badge.tsx @@ -0,0 +1,37 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", + { + variants: { + variant: { + default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", + secondary: + "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", + destructive: + "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Badge({ + className, + variant, + asChild = false, + ...props +}: React.ComponentProps<"span"> & VariantProps & { asChild?: boolean }) { + const Comp = asChild ? Slot : "span" + + return +} + +export { Badge, badgeVariants } diff --git a/ui/src/components/ui/breadcrumb.tsx b/ui/src/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..2fb5358 --- /dev/null +++ b/ui/src/components/ui/breadcrumb.tsx @@ -0,0 +1,102 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { ChevronRight, MoreHorizontal } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { + return