Compare commits
10 Commits
feature/ag
...
c65dc3af47
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c65dc3af47 | ||
|
|
6f395ed1ae | ||
|
|
e6e85564e7 | ||
|
|
c7a090f78a | ||
|
|
8cc2775fe4 | ||
|
|
0b64538754 | ||
|
|
8009ca20ff | ||
|
|
7a5b9471e0 | ||
|
|
bb55e37b49 | ||
| 9a264a61ac |
17
.github/workflows/test.yml
vendored
17
.github/workflows/test.yml
vendored
@@ -12,11 +12,8 @@ on:
|
||||
|
||||
|
||||
jobs:
|
||||
# setup is now handled by a composite action used by downstream jobs to keep
|
||||
# the workflow DRY. The composite action performs checkout, cache restore and
|
||||
# toolchain setup.
|
||||
|
||||
test:
|
||||
test-crates:
|
||||
needs: frontend-build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -39,7 +36,7 @@ jobs:
|
||||
- name: Run tests
|
||||
run: cargo test --all-features
|
||||
|
||||
lint:
|
||||
lint-crates:
|
||||
needs: frontend-build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -83,13 +80,13 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: apps/frontend/pnpm-lock.yaml
|
||||
cache-dependency-path: pnpm-lock.yaml
|
||||
|
||||
- name: Install frontend dependencies
|
||||
run: |
|
||||
cd apps/frontend
|
||||
pnpm install
|
||||
|
||||
|
||||
- name: Run frontend linter
|
||||
run: |
|
||||
cd apps/frontend
|
||||
@@ -114,7 +111,7 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: apps/frontend/pnpm-lock.yaml
|
||||
cache-dependency-path: pnpm-lock.yaml
|
||||
|
||||
- name: Install frontend dependencies
|
||||
run: |
|
||||
@@ -142,12 +139,12 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: apps/frontend/pnpm-lock.yaml
|
||||
cache-dependency-path: pnpm-lock.yaml
|
||||
|
||||
- name: Install frontend dependencies
|
||||
run: |
|
||||
cd apps/frontend
|
||||
pnpm install
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build frontend
|
||||
run: |
|
||||
|
||||
79
.github/workflows/verify.yml
vendored
79
.github/workflows/verify.yml
vendored
@@ -11,18 +11,15 @@ on:
|
||||
|
||||
|
||||
jobs:
|
||||
# setup is now handled by a composite action used by downstream jobs to keep
|
||||
# the workflow DRY. The composite action performs checkout, cache restore and
|
||||
# toolchain setup.
|
||||
|
||||
verify-generated-code:
|
||||
verify-generated-database-code:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
- name: Setup Rust, checkout and restore caches
|
||||
uses: ./.github/actions/setup-rust
|
||||
|
||||
@@ -32,14 +29,62 @@ jobs:
|
||||
cargo run -- db:migrate_and_generate --output-path ../../public/database/src/generated/entities
|
||||
- name: Check for uncommitted changes in /generated/
|
||||
run: |
|
||||
if [[ -n $(git status --porcelain | grep '^ M .*\/generated\/') ]]; then
|
||||
if [[ -n $(git status --porcelain --untracked-files=all | grep '/generated/') ]]; then
|
||||
echo "Generated code is not up to date. Please run the code generation locally and commit the changes."
|
||||
git status --porcelain | grep '^ M .*\/generated\/'
|
||||
git status --porcelain --untracked-files=all | grep '/generated/'
|
||||
exit 1
|
||||
else
|
||||
echo "Generated code is up to date."
|
||||
fi
|
||||
|
||||
verify-generated-agent-code:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
|
||||
- name: Setup Rust, checkout and restore caches
|
||||
uses: ./.github/actions/setup-rust
|
||||
|
||||
- name: Setup PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
run_install: false
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: pnpm-lock.yaml
|
||||
|
||||
- name: Install root dependencies
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
- name: generate agent client code
|
||||
run: |
|
||||
pnpm just generate-agent-client
|
||||
|
||||
|
||||
- name: Check for uncommitted changes in agent client code
|
||||
run: |
|
||||
if [[ -n $(git status --porcelain --untracked-files=all | grep 'public/agent-client/') ]]; then
|
||||
echo "Agent client code is not up to date. Please run the agent client code generation locally and commit the changes."
|
||||
git status --porcelain --untracked-files=all | grep 'public/agent-client/'
|
||||
exit 1
|
||||
else
|
||||
echo "Agent client code is up to date."
|
||||
fi
|
||||
|
||||
verify-openapi-spec:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -83,7 +128,7 @@ jobs:
|
||||
- name: Setup Rust, checkout and restore caches
|
||||
if: steps.check_changes.outputs.changed == 'true'
|
||||
uses: ./.github/actions/setup-rust
|
||||
|
||||
|
||||
- name: Generate dummy frontend build (to satisfy dependencies)
|
||||
if: steps.check_changes.outputs.changed == 'true'
|
||||
run: |
|
||||
@@ -95,13 +140,13 @@ jobs:
|
||||
run: |
|
||||
cd apps/api
|
||||
cargo run -- generate:openapi --output-path ./swagger.json
|
||||
|
||||
|
||||
- name: Check for uncommitted changes in swagger.json
|
||||
if: steps.check_changes.outputs.changed == 'true'
|
||||
run: |
|
||||
if [[ -n $(git status --porcelain | grep '^ M apps/api/swagger.json') ]]; then
|
||||
if [[ -n $(git status --porcelain --untracked-files=all | grep 'apps/api/swagger.json') ]]; then
|
||||
echo "OpenAPI spec is not up to date. Please run the OpenAPI generation locally and commit the changes."
|
||||
git status --porcelain | grep '^ M apps/api/swagger.json'
|
||||
git status --porcelain --untracked-files=all | grep 'apps/api/swagger.json'
|
||||
exit 1
|
||||
else
|
||||
echo "OpenAPI spec is up to date."
|
||||
@@ -165,14 +210,14 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: apps/frontend/pnpm-lock.yaml
|
||||
|
||||
cache-dependency-path: pnpm-lock.yaml
|
||||
|
||||
- name: Install frontend dependencies
|
||||
if: steps.check_swagger_changes.outputs.changed == 'true'
|
||||
run: |
|
||||
cd apps/frontend
|
||||
pnpm install
|
||||
|
||||
|
||||
- name: Generate frontend API client
|
||||
if: steps.check_swagger_changes.outputs.changed == 'true'
|
||||
run: |
|
||||
@@ -182,14 +227,14 @@ jobs:
|
||||
- name: Check for uncommitted changes in frontend API client
|
||||
if: steps.check_swagger_changes.outputs.changed == 'true'
|
||||
run: |
|
||||
if [[ -n $(git status --porcelain | grep '^ M apps/frontend/app/generated/api-client') ]]; then
|
||||
if [[ -n $(git status --porcelain --untracked-files=all | grep 'apps/frontend/app/generated/api-client') ]]; then
|
||||
echo "Frontend API client is not up to date. Please run the API client generation locally and commit the changes."
|
||||
git status --porcelain | grep '^ M apps/frontend/app/generated/api-client'
|
||||
git status --porcelain --untracked-files=all | grep 'apps/frontend/app/generated/api-client'
|
||||
exit 1
|
||||
else
|
||||
echo "Frontend API client is up to date."
|
||||
fi
|
||||
|
||||
|
||||
- name: Skip frontend API client generation (no relevant changes)
|
||||
if: steps.check_swagger_changes.outputs.changed == 'false'
|
||||
run: echo "No changes in apps/api/swagger.json nor apps/frontend/app/generated/api-client, skipping frontend API client generation verification."
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -27,3 +27,5 @@ target
|
||||
.env.generated
|
||||
|
||||
generated-config.yaml
|
||||
|
||||
node_modules/
|
||||
|
||||
505
Cargo.lock
generated
505
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@ members = [
|
||||
"apps/container",
|
||||
"apps/cli",
|
||||
"apps/agent",
|
||||
"public/agent-client",
|
||||
"public/shared",
|
||||
"public/database",
|
||||
"public/migration"
|
||||
|
||||
@@ -13,3 +13,4 @@ serde = { version = "1.0.228", features = ["std", "derive"] }
|
||||
tokio-cron-scheduler = { version = "0.15.1", features = ["signal"] }
|
||||
clap = { version = "4", features = ["derive", "env"] }
|
||||
nix = { version = "0.30.1", features = ["user", "fs"] }
|
||||
utoipa = { version = "5.4.0", features = ["macros", "axum_extras", "chrono", "decimal", "uuid", "time", "openapi_extensions"] }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
mod commands;
|
||||
mod openapi;
|
||||
mod routes;
|
||||
|
||||
use axum::routing::get;
|
||||
@@ -13,6 +14,7 @@ use tokio::net::UnixListener;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
use crate::commands::NginxService;
|
||||
use crate::openapi::{GenerateOpenapiArgs, generate_openapi_doc};
|
||||
use crate::routes::{status, validate, validate_and_reload, write_config};
|
||||
|
||||
const SOCK_ENV: &str = "YANPM_AGENT_SOCK";
|
||||
@@ -43,6 +45,19 @@ struct Args {
|
||||
/// GID to set on the unix socket, default: current user's primary group
|
||||
#[arg(long, default_value_t = String::from(SOCK_GID_DEFAULT), env = SOCK_GID_ENV)]
|
||||
sock_gid: String,
|
||||
|
||||
#[command(subcommand)]
|
||||
command: Option<SubCommand>,
|
||||
}
|
||||
|
||||
#[derive(clap::Subcommand, Debug)]
|
||||
pub enum SubCommand {
|
||||
/// Generate OpenAPI spec to file or stdout
|
||||
GenerateOpenapi {
|
||||
/// Output file path.
|
||||
#[arg(short = 'o', long)]
|
||||
output: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
@@ -59,6 +74,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
if let Some(cmd) = &args.command {
|
||||
match cmd {
|
||||
SubCommand::GenerateOpenapi { output } => {
|
||||
generate_openapi_doc(&GenerateOpenapiArgs {
|
||||
output: output.clone(),
|
||||
})
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (sock, nginx_config_dir, sock_perm, sock_gid) = get_args(&args).await?;
|
||||
|
||||
let path = PathBuf::from(&sock);
|
||||
|
||||
45
apps/agent/src/openapi.rs
Normal file
45
apps/agent/src/openapi.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use tracing::info;
|
||||
use utoipa::OpenApi;
|
||||
|
||||
pub mod tag {
|
||||
/// nginx
|
||||
pub const NGINX_TAG: &str = "Nginx Agent";
|
||||
}
|
||||
|
||||
#[derive(utoipa::OpenApi)]
|
||||
#[openapi(
|
||||
paths(
|
||||
crate::routes::status,
|
||||
crate::routes::validate,
|
||||
crate::routes::validate_and_reload,
|
||||
crate::routes::write_config,
|
||||
),
|
||||
components(
|
||||
schemas(crate::routes::StatusResp),
|
||||
schemas(crate::routes::ValidateAndReloadResp),
|
||||
schemas(crate::routes::ValidateBody),
|
||||
schemas(crate::routes::WriteConfigBody),
|
||||
schemas(crate::routes::ValidateAndReloadBody),
|
||||
),
|
||||
tags(
|
||||
(name = tag::NGINX_TAG, description = "Nginx Agent API"),
|
||||
)
|
||||
)]
|
||||
struct ApiDoc;
|
||||
|
||||
pub struct GenerateOpenapiArgs {
|
||||
pub output: String,
|
||||
}
|
||||
|
||||
pub async fn generate_openapi_doc(
|
||||
args: &GenerateOpenapiArgs,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
info!("Generating OpenAPI documentation...");
|
||||
let doc = ApiDoc::openapi();
|
||||
let json = doc
|
||||
.to_pretty_json()
|
||||
.expect("Failed to serialize OpenAPI doc to JSON");
|
||||
std::fs::write(&args.output, json).expect("Failed to write OpenAPI doc to file");
|
||||
info!("OpenAPI documentation generated at {}", args.output);
|
||||
Ok(())
|
||||
}
|
||||
@@ -9,28 +9,46 @@ use tracing::warn;
|
||||
|
||||
use crate::commands::NginxService;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, utoipa::ToSchema)]
|
||||
pub struct StatusResp {
|
||||
pub ok: bool,
|
||||
}
|
||||
|
||||
/// Health check endpoint
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/status",
|
||||
responses(
|
||||
(status = 200, description = "Status response", body = StatusResp)
|
||||
),
|
||||
tag = crate::openapi::tag::NGINX_TAG
|
||||
)]
|
||||
pub async fn status() -> impl IntoResponse {
|
||||
let resp = StatusResp { ok: true };
|
||||
(axum::http::StatusCode::OK, axum::Json(resp))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, utoipa::ToSchema)]
|
||||
pub struct ValidateAndReloadResp {
|
||||
pub rc: i32,
|
||||
pub ro: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, utoipa::ToSchema)]
|
||||
pub struct ValidateBody {
|
||||
config_name: String,
|
||||
timestamp: u64,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/validate",
|
||||
request_body = ValidateBody,
|
||||
responses(
|
||||
(status = 200, description = "Validation response", body = serde_json::Value)
|
||||
),
|
||||
tag = crate::openapi::tag::NGINX_TAG
|
||||
)]
|
||||
pub async fn validate(
|
||||
State(nginx_controller): State<Arc<NginxService>>,
|
||||
Json(payload): Json<Value>,
|
||||
@@ -57,12 +75,21 @@ pub async fn validate(
|
||||
(axum::http::StatusCode::OK, axum::Json(resp)).into_response()
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, utoipa::ToSchema)]
|
||||
pub struct ValidateAndReloadBody {
|
||||
config_name: String,
|
||||
timestamp: u64,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/validate_and_reload",
|
||||
request_body = ValidateAndReloadBody,
|
||||
responses(
|
||||
(status = 200, description = "Validate and reload response", body = ValidateAndReloadResp)
|
||||
),
|
||||
tag = crate::openapi::tag::NGINX_TAG
|
||||
)]
|
||||
pub async fn validate_and_reload(
|
||||
State(nginx_controller): State<Arc<NginxService>>,
|
||||
Json(payload): Json<Value>,
|
||||
@@ -96,13 +123,23 @@ pub async fn validate_and_reload(
|
||||
(axum::http::StatusCode::OK, axum::Json(resp)).into_response()
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, utoipa::ToSchema)]
|
||||
pub struct WriteConfigBody {
|
||||
config_name: String,
|
||||
timestamp: u64,
|
||||
content: String,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/write_config",
|
||||
request_body = WriteConfigBody,
|
||||
responses(
|
||||
(status = 200, description = "Write config response"),
|
||||
(status = 500, description = "Internal server error", body = serde_json::Value)
|
||||
),
|
||||
tag = crate::openapi::tag::NGINX_TAG
|
||||
)]
|
||||
pub async fn write_config(
|
||||
State(nginx_controller): State<Arc<NginxService>>,
|
||||
Json(payload): Json<Value>,
|
||||
|
||||
215
apps/agent/swagger.json
Normal file
215
apps/agent/swagger.json
Normal file
@@ -0,0 +1,215 @@
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "yanpm-agent",
|
||||
"description": "",
|
||||
"license": {
|
||||
"name": ""
|
||||
},
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"paths": {
|
||||
"/status": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Nginx Agent"
|
||||
],
|
||||
"summary": "Health check endpoint",
|
||||
"operationId": "status",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Status response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/StatusResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/validate": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Nginx Agent"
|
||||
],
|
||||
"operationId": "validate",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ValidateBody"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Validation response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/validate_and_reload": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Nginx Agent"
|
||||
],
|
||||
"operationId": "validate_and_reload",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ValidateAndReloadBody"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Validate and reload response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ValidateAndReloadResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/write_config": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Nginx Agent"
|
||||
],
|
||||
"operationId": "write_config",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/WriteConfigBody"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Write config response"
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal server error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"StatusResp": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ok"
|
||||
],
|
||||
"properties": {
|
||||
"ok": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ValidateAndReloadBody": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"config_name",
|
||||
"timestamp"
|
||||
],
|
||||
"properties": {
|
||||
"config_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"ValidateAndReloadResp": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"rc",
|
||||
"ro"
|
||||
],
|
||||
"properties": {
|
||||
"rc": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"ro": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ValidateBody": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"config_name",
|
||||
"timestamp"
|
||||
],
|
||||
"properties": {
|
||||
"config_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"WriteConfigBody": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"config_name",
|
||||
"timestamp",
|
||||
"content"
|
||||
],
|
||||
"properties": {
|
||||
"config_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "Nginx Agent",
|
||||
"description": "Nginx Agent API"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,6 +6,7 @@ edition = "2024"
|
||||
[dependencies]
|
||||
database = { path = "../../public/database" }
|
||||
migration = { path = "../../public/migration" }
|
||||
agent_client = { path = "../../public/agent-client" }
|
||||
|
||||
axum = { version = "0.8.7", features = ["form", "http1", "http2", "json", "matched-path", "original-uri", "query", "tokio", "tower-log", "tracing", "macros"] }
|
||||
axum-extra = { version = "0.12.2", features = ["cookie"] }
|
||||
@@ -28,4 +29,7 @@ argon2 = { version = "0.5.3", features = ["std"] }
|
||||
jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] }
|
||||
uuid = { version = "1.19.0", features = ["v4", "serde", "fast-rng"] }
|
||||
tower-http = { version = "0.6.8", features = ["cors"] }
|
||||
reqwest = { version = "^0.12", features = ["json", "multipart", "stream"] }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod agent_client;
|
||||
pub mod auth;
|
||||
pub mod server_state;
|
||||
pub mod settings;
|
||||
|
||||
92
apps/api/src/services/agent_client.rs
Normal file
92
apps/api/src/services/agent_client.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use agent_client::apis::{ApiClient, configuration::Configuration};
|
||||
|
||||
pub struct AgentService {
|
||||
client: Arc<ApiClient>,
|
||||
}
|
||||
|
||||
impl AgentService {
|
||||
pub fn new(config: impl Into<Arc<Configuration>>) -> Self {
|
||||
let client = ApiClient::new(config.into());
|
||||
AgentService {
|
||||
client: Arc::new(client),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_client(&self) -> Arc<ApiClient> {
|
||||
Arc::clone(&self.client)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use agent_client::{
|
||||
apis::{Api, nginx_agent_api::StatusSuccess},
|
||||
models::StatusResp,
|
||||
};
|
||||
use axum::{http::StatusCode, response::Json};
|
||||
use std::time::Duration;
|
||||
use tempfile::tempdir;
|
||||
use tokio::time::sleep;
|
||||
|
||||
#[test]
|
||||
fn test_agent_service_creation() {
|
||||
let config = Configuration::default();
|
||||
let service = AgentService::new(config);
|
||||
let client = service.get_client();
|
||||
assert!(Arc::ptr_eq(&client, &service.client));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_agent_socket_support() {
|
||||
// create temporary socket path
|
||||
let dir = tempdir().expect("Failed to create temp dir");
|
||||
let socket_path = dir.path().join("agent.sock");
|
||||
|
||||
// create axum app with a simple /status route
|
||||
let app = axum::Router::new().route(
|
||||
"/status",
|
||||
axum::routing::get(|| async {
|
||||
let result: (StatusCode, StatusResp) = (StatusCode::OK, StatusResp { ok: true });
|
||||
|
||||
(result.0, Json(result.1))
|
||||
}),
|
||||
);
|
||||
|
||||
// bind tokio unix listener and serve in background
|
||||
let listener =
|
||||
tokio::net::UnixListener::bind(&socket_path).expect("Failed to bind to unix socket");
|
||||
let server_fut = axum::serve::serve(listener, app);
|
||||
let _srv = tokio::spawn(async move {
|
||||
let _ = server_fut.await;
|
||||
});
|
||||
|
||||
// give server a moment to start
|
||||
sleep(Duration::from_millis(50)).await;
|
||||
|
||||
let client: ApiClient = ApiClient::new(Arc::new(Configuration {
|
||||
base_path: "http://localhost".to_string(),
|
||||
client: reqwest::Client::builder()
|
||||
.unix_socket(socket_path.clone())
|
||||
.build()
|
||||
.expect("Failed to build reqwest client"),
|
||||
..Default::default()
|
||||
}));
|
||||
|
||||
let res = client
|
||||
.nginx_agent_api()
|
||||
.status()
|
||||
.await
|
||||
.expect("Failed to get status");
|
||||
let body = res.entity.expect("Response entity is missing");
|
||||
|
||||
assert!(res.status.is_success());
|
||||
if let StatusSuccess::Status200(body) = body {
|
||||
assert!(body.ok);
|
||||
} else {
|
||||
panic!("Unexpected response body");
|
||||
}
|
||||
}
|
||||
}
|
||||
24
justfile
24
justfile
@@ -50,9 +50,31 @@ generate-openapi:
|
||||
# Generate API client for frontend
|
||||
cd apps/frontend && \
|
||||
pnpm generate:openapi
|
||||
# Generate API client for agent
|
||||
cd apps/agent && \
|
||||
cargo run -- generate-openapi --output swagger.json
|
||||
|
||||
generate-agent-client:
|
||||
# Generate API client for agent
|
||||
pnpm openapi-generator-cli generate \
|
||||
-g rust --skip-validate-spec \
|
||||
-o ./public/agent-client -i ./apps/agent/swagger.json \
|
||||
--additional-properties=library=reqwest-trait \
|
||||
--additional-properties=mockall=true \
|
||||
--additional-properties=packageName=agent_client \
|
||||
--additional-properties=packageVersion=0.1.0 \
|
||||
--additional-properties=supportAsync=true \
|
||||
--additional-properties=supportMultipleResponses=true \
|
||||
--additional-properties=topLevelApiClient=true \
|
||||
--additional-properties=useSingleRequestParameter=true
|
||||
# format generated code
|
||||
cd public/agent-client && \
|
||||
cargo fmt
|
||||
# append lint allows/forbids to the end of Cargo.toml to disable warnings in generated code and forbid unsafe code
|
||||
cd public/agent-client && \
|
||||
echo '\n[lints.clippy]\nall = "allow"\n[lints.rust]\nunsafe_code = "forbid"\n' >> Cargo.toml
|
||||
|
||||
generate-all: generate-entity generate-openapi
|
||||
generate-all: generate-entity generate-openapi generate-agent-client
|
||||
|
||||
build-frontend:
|
||||
# build frontend assets
|
||||
|
||||
7
openapitools.json
Normal file
7
openapitools.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
|
||||
"spaces": 2,
|
||||
"generator-cli": {
|
||||
"version": "7.18.0"
|
||||
}
|
||||
}
|
||||
6
package.json
Normal file
6
package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@openapitools/openapi-generator-cli": "^2.26.0",
|
||||
"rust-just": "^1.44.0"
|
||||
}
|
||||
}
|
||||
3418
apps/frontend/pnpm-lock.yaml → pnpm-lock.yaml
generated
3418
apps/frontend/pnpm-lock.yaml → pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
7
pnpm-workspace.yaml
Normal file
7
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
packages:
|
||||
- apps/frontend
|
||||
|
||||
onlyBuiltDependencies:
|
||||
- '@nestjs/core'
|
||||
- '@openapitools/openapi-generator-cli'
|
||||
- esbuild
|
||||
3
public/agent-client/.gitignore
vendored
Normal file
3
public/agent-client/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/target/
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
23
public/agent-client/.openapi-generator-ignore
Normal file
23
public/agent-client/.openapi-generator-ignore
Normal file
@@ -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
|
||||
21
public/agent-client/.openapi-generator/FILES
Normal file
21
public/agent-client/.openapi-generator/FILES
Normal file
@@ -0,0 +1,21 @@
|
||||
.gitignore
|
||||
.travis.yml
|
||||
Cargo.toml
|
||||
README.md
|
||||
docs/NginxAgentApi.md
|
||||
docs/StatusResp.md
|
||||
docs/ValidateAndReloadBody.md
|
||||
docs/ValidateAndReloadResp.md
|
||||
docs/ValidateBody.md
|
||||
docs/WriteConfigBody.md
|
||||
git_push.sh
|
||||
src/apis/configuration.rs
|
||||
src/apis/mod.rs
|
||||
src/apis/nginx_agent_api.rs
|
||||
src/lib.rs
|
||||
src/models/mod.rs
|
||||
src/models/status_resp.rs
|
||||
src/models/validate_and_reload_body.rs
|
||||
src/models/validate_and_reload_resp.rs
|
||||
src/models/validate_body.rs
|
||||
src/models/write_config_body.rs
|
||||
1
public/agent-client/.openapi-generator/VERSION
Normal file
1
public/agent-client/.openapi-generator/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
7.18.0
|
||||
1
public/agent-client/.travis.yml
Normal file
1
public/agent-client/.travis.yml
Normal file
@@ -0,0 +1 @@
|
||||
language: rust
|
||||
27
public/agent-client/Cargo.toml
Normal file
27
public/agent-client/Cargo.toml
Normal file
@@ -0,0 +1,27 @@
|
||||
[package]
|
||||
name = "agent_client"
|
||||
version = "0.1.0"
|
||||
authors = ["OpenAPI Generator team and contributors"]
|
||||
description = "No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)"
|
||||
license = ""
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = "^1.0"
|
||||
serde_repr = "^0.1"
|
||||
url = "^2.5"
|
||||
async-trait = "^0.1"
|
||||
reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart", "stream"] }
|
||||
mockall = { version = "^0.13", optional = true}
|
||||
[features]
|
||||
default = ["native-tls"]
|
||||
native-tls = ["reqwest/native-tls"]
|
||||
rustls-tls = ["reqwest/rustls-tls"]
|
||||
mockall = ["dep:mockall"]
|
||||
|
||||
[lints.clippy]
|
||||
all = "allow"
|
||||
[lints.rust]
|
||||
unsafe_code = "forbid"
|
||||
|
||||
53
public/agent-client/README.md
Normal file
53
public/agent-client/README.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Rust API client for agent_client
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client.
|
||||
|
||||
- API version: 0.1.0
|
||||
- Package version: 0.1.0
|
||||
- Generator version: 7.18.0
|
||||
- Build package: `org.openapitools.codegen.languages.RustClientCodegen`
|
||||
|
||||
## Installation
|
||||
|
||||
Put the package under your project folder in a directory named `agent_client` and add the following to `Cargo.toml` under `[dependencies]`:
|
||||
|
||||
```
|
||||
agent_client = { path = "./agent_client" }
|
||||
```
|
||||
|
||||
## Documentation for API Endpoints
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
*NginxAgentApi* | [**status**](docs/NginxAgentApi.md#status) | **GET** /status | Health check endpoint
|
||||
*NginxAgentApi* | [**validate**](docs/NginxAgentApi.md#validate) | **POST** /validate |
|
||||
*NginxAgentApi* | [**validate_and_reload**](docs/NginxAgentApi.md#validate_and_reload) | **POST** /validate_and_reload |
|
||||
*NginxAgentApi* | [**write_config**](docs/NginxAgentApi.md#write_config) | **POST** /write_config |
|
||||
|
||||
|
||||
## Documentation For Models
|
||||
|
||||
- [StatusResp](docs/StatusResp.md)
|
||||
- [ValidateAndReloadBody](docs/ValidateAndReloadBody.md)
|
||||
- [ValidateAndReloadResp](docs/ValidateAndReloadResp.md)
|
||||
- [ValidateBody](docs/ValidateBody.md)
|
||||
- [WriteConfigBody](docs/WriteConfigBody.md)
|
||||
|
||||
|
||||
To get access to the crate's generated documentation, use:
|
||||
|
||||
```
|
||||
cargo doc --open
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
|
||||
121
public/agent-client/docs/NginxAgentApi.md
Normal file
121
public/agent-client/docs/NginxAgentApi.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# \NginxAgentApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**status**](NginxAgentApi.md#status) | **GET** /status | Health check endpoint
|
||||
[**validate**](NginxAgentApi.md#validate) | **POST** /validate |
|
||||
[**validate_and_reload**](NginxAgentApi.md#validate_and_reload) | **POST** /validate_and_reload |
|
||||
[**write_config**](NginxAgentApi.md#write_config) | **POST** /write_config |
|
||||
|
||||
|
||||
|
||||
## status
|
||||
|
||||
> models::StatusResp status()
|
||||
Health check endpoint
|
||||
|
||||
### Parameters
|
||||
|
||||
This endpoint does not need any parameter.
|
||||
|
||||
### Return type
|
||||
|
||||
[**models::StatusResp**](StatusResp.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)
|
||||
|
||||
|
||||
## validate
|
||||
|
||||
> serde_json::Value validate(validate_body)
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Required | Notes
|
||||
------------- | ------------- | ------------- | ------------- | -------------
|
||||
**validate_body** | [**ValidateBody**](ValidateBody.md) | | [required] |
|
||||
|
||||
### Return type
|
||||
|
||||
[**serde_json::Value**](serde_json::Value.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)
|
||||
|
||||
|
||||
## validate_and_reload
|
||||
|
||||
> models::ValidateAndReloadResp validate_and_reload(validate_and_reload_body)
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Required | Notes
|
||||
------------- | ------------- | ------------- | ------------- | -------------
|
||||
**validate_and_reload_body** | [**ValidateAndReloadBody**](ValidateAndReloadBody.md) | | [required] |
|
||||
|
||||
### Return type
|
||||
|
||||
[**models::ValidateAndReloadResp**](ValidateAndReloadResp.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)
|
||||
|
||||
|
||||
## write_config
|
||||
|
||||
> write_config(write_config_body)
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Required | Notes
|
||||
------------- | ------------- | ------------- | ------------- | -------------
|
||||
**write_config_body** | [**WriteConfigBody**](WriteConfigBody.md) | | [required] |
|
||||
|
||||
### Return type
|
||||
|
||||
(empty response body)
|
||||
|
||||
### 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)
|
||||
|
||||
11
public/agent-client/docs/StatusResp.md
Normal file
11
public/agent-client/docs/StatusResp.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# StatusResp
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**ok** | **bool** | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
121
public/agent-client/docs/TagNginxtagApi.md
Normal file
121
public/agent-client/docs/TagNginxtagApi.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# \TagNginxtagApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**status**](TagNginxtagApi.md#status) | **GET** /status | Health check endpoint
|
||||
[**validate**](TagNginxtagApi.md#validate) | **POST** /validate |
|
||||
[**validate_and_reload**](TagNginxtagApi.md#validate_and_reload) | **POST** /validate_and_reload |
|
||||
[**write_config**](TagNginxtagApi.md#write_config) | **POST** /write_config |
|
||||
|
||||
|
||||
|
||||
## status
|
||||
|
||||
> models::StatusResp status()
|
||||
Health check endpoint
|
||||
|
||||
### Parameters
|
||||
|
||||
This endpoint does not need any parameter.
|
||||
|
||||
### Return type
|
||||
|
||||
[**models::StatusResp**](StatusResp.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)
|
||||
|
||||
|
||||
## validate
|
||||
|
||||
> serde_json::Value validate(validate_body)
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Required | Notes
|
||||
------------- | ------------- | ------------- | ------------- | -------------
|
||||
**validate_body** | [**ValidateBody**](ValidateBody.md) | | [required] |
|
||||
|
||||
### Return type
|
||||
|
||||
[**serde_json::Value**](serde_json::Value.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)
|
||||
|
||||
|
||||
## validate_and_reload
|
||||
|
||||
> models::ValidateAndReloadResp validate_and_reload(validate_and_reload_body)
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Required | Notes
|
||||
------------- | ------------- | ------------- | ------------- | -------------
|
||||
**validate_and_reload_body** | [**ValidateAndReloadBody**](ValidateAndReloadBody.md) | | [required] |
|
||||
|
||||
### Return type
|
||||
|
||||
[**models::ValidateAndReloadResp**](ValidateAndReloadResp.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)
|
||||
|
||||
|
||||
## write_config
|
||||
|
||||
> write_config(write_config_body)
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Required | Notes
|
||||
------------- | ------------- | ------------- | ------------- | -------------
|
||||
**write_config_body** | [**WriteConfigBody**](WriteConfigBody.md) | | [required] |
|
||||
|
||||
### Return type
|
||||
|
||||
(empty response body)
|
||||
|
||||
### 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)
|
||||
|
||||
12
public/agent-client/docs/ValidateAndReloadBody.md
Normal file
12
public/agent-client/docs/ValidateAndReloadBody.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# ValidateAndReloadBody
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**config_name** | **String** | |
|
||||
**timestamp** | **i64** | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
12
public/agent-client/docs/ValidateAndReloadResp.md
Normal file
12
public/agent-client/docs/ValidateAndReloadResp.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# ValidateAndReloadResp
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**rc** | **i32** | |
|
||||
**ro** | **String** | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
12
public/agent-client/docs/ValidateBody.md
Normal file
12
public/agent-client/docs/ValidateBody.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# ValidateBody
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**config_name** | **String** | |
|
||||
**timestamp** | **i64** | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
13
public/agent-client/docs/WriteConfigBody.md
Normal file
13
public/agent-client/docs/WriteConfigBody.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# WriteConfigBody
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**config_name** | **String** | |
|
||||
**content** | **String** | |
|
||||
**timestamp** | **i64** | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
57
public/agent-client/git_push.sh
Normal file
57
public/agent-client/git_push.sh
Normal file
@@ -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="GIT_USER_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||
fi
|
||||
|
||||
if [ "$git_repo_id" = "" ]; then
|
||||
git_repo_id="GIT_REPO_ID"
|
||||
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'
|
||||
48
public/agent-client/src/apis/configuration.rs
Normal file
48
public/agent-client/src/apis/configuration.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* yanpm-agent
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1.0
|
||||
*
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Configuration {
|
||||
pub base_path: String,
|
||||
pub user_agent: Option<String>,
|
||||
pub client: reqwest::Client,
|
||||
pub basic_auth: Option<BasicAuth>,
|
||||
pub oauth_access_token: Option<String>,
|
||||
pub bearer_access_token: Option<String>,
|
||||
pub api_key: Option<ApiKey>,
|
||||
}
|
||||
|
||||
pub type BasicAuth = (String, Option<String>);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ApiKey {
|
||||
pub prefix: Option<String>,
|
||||
pub key: String,
|
||||
}
|
||||
|
||||
impl Configuration {
|
||||
pub fn new() -> Configuration {
|
||||
Configuration::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Configuration {
|
||||
fn default() -> Self {
|
||||
Configuration {
|
||||
base_path: "http://localhost".to_owned(),
|
||||
user_agent: Some("OpenAPI-Generator/0.1.0/rust".to_owned()),
|
||||
client: reqwest::Client::new(),
|
||||
basic_auth: None,
|
||||
oauth_access_token: None,
|
||||
bearer_access_token: None,
|
||||
api_key: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
165
public/agent-client/src/apis/mod.rs
Normal file
165
public/agent-client/src/apis/mod.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ResponseContent<T> {
|
||||
pub status: reqwest::StatusCode,
|
||||
pub content: String,
|
||||
pub entity: Option<T>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error<T> {
|
||||
Reqwest(reqwest::Error),
|
||||
Serde(serde_json::Error),
|
||||
Io(std::io::Error),
|
||||
ResponseError(ResponseContent<T>),
|
||||
}
|
||||
|
||||
impl<T> fmt::Display for Error<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let (module, e) = match self {
|
||||
Error::Reqwest(e) => ("reqwest", e.to_string()),
|
||||
Error::Serde(e) => ("serde", e.to_string()),
|
||||
Error::Io(e) => ("IO", e.to_string()),
|
||||
Error::ResponseError(e) => ("response", format!("status code {}", e.status)),
|
||||
};
|
||||
write!(f, "error in {}: {}", module, e)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug> error::Error for Error<T> {
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
Some(match self {
|
||||
Error::Reqwest(e) => e,
|
||||
Error::Serde(e) => e,
|
||||
Error::Io(e) => e,
|
||||
Error::ResponseError(_) => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<reqwest::Error> for Error<T> {
|
||||
fn from(e: reqwest::Error) -> Self {
|
||||
Error::Reqwest(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<serde_json::Error> for Error<T> {
|
||||
fn from(e: serde_json::Error) -> Self {
|
||||
Error::Serde(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<std::io::Error> for Error<T> {
|
||||
fn from(e: std::io::Error) -> Self {
|
||||
Error::Io(e)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn urlencode<T: AsRef<str>>(s: T) -> String {
|
||||
::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect()
|
||||
}
|
||||
|
||||
pub fn parse_deep_object(prefix: &str, value: &serde_json::Value) -> Vec<(String, String)> {
|
||||
if let serde_json::Value::Object(object) = value {
|
||||
let mut params = vec![];
|
||||
|
||||
for (key, value) in object {
|
||||
match value {
|
||||
serde_json::Value::Object(_) => params.append(&mut parse_deep_object(
|
||||
&format!("{}[{}]", prefix, key),
|
||||
value,
|
||||
)),
|
||||
serde_json::Value::Array(array) => {
|
||||
for (i, value) in array.iter().enumerate() {
|
||||
params.append(&mut parse_deep_object(
|
||||
&format!("{}[{}][{}]", prefix, key, i),
|
||||
value,
|
||||
));
|
||||
}
|
||||
}
|
||||
serde_json::Value::String(s) => {
|
||||
params.push((format!("{}[{}]", prefix, key), s.clone()))
|
||||
}
|
||||
_ => params.push((format!("{}[{}]", prefix, key), value.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
unimplemented!("Only objects are supported with style=deepObject")
|
||||
}
|
||||
|
||||
/// Internal use only
|
||||
/// A content type supported by this client.
|
||||
#[allow(dead_code)]
|
||||
enum ContentType {
|
||||
Json,
|
||||
Text,
|
||||
Unsupported(String),
|
||||
}
|
||||
|
||||
impl From<&str> for ContentType {
|
||||
fn from(content_type: &str) -> Self {
|
||||
if content_type.starts_with("application") && content_type.contains("json") {
|
||||
return Self::Json;
|
||||
} else if content_type.starts_with("text/plain") {
|
||||
return Self::Text;
|
||||
} else {
|
||||
return Self::Unsupported(content_type.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod nginx_agent_api;
|
||||
|
||||
pub mod configuration;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait Api {
|
||||
fn nginx_agent_api(&self) -> &dyn nginx_agent_api::NginxAgentApi;
|
||||
}
|
||||
|
||||
pub struct ApiClient {
|
||||
nginx_agent_api: Box<dyn nginx_agent_api::NginxAgentApi>,
|
||||
}
|
||||
|
||||
impl ApiClient {
|
||||
pub fn new(configuration: Arc<configuration::Configuration>) -> Self {
|
||||
Self {
|
||||
nginx_agent_api: Box::new(nginx_agent_api::NginxAgentApiClient::new(
|
||||
configuration.clone(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Api for ApiClient {
|
||||
fn nginx_agent_api(&self) -> &dyn nginx_agent_api::NginxAgentApi {
|
||||
self.nginx_agent_api.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mockall")]
|
||||
pub struct MockApiClient {
|
||||
pub nginx_agent_api_mock: nginx_agent_api::MockNginxAgentApi,
|
||||
}
|
||||
|
||||
#[cfg(feature = "mockall")]
|
||||
impl MockApiClient {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
nginx_agent_api_mock: nginx_agent_api::MockNginxAgentApi::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mockall")]
|
||||
impl Api for MockApiClient {
|
||||
fn nginx_agent_api(&self) -> &dyn nginx_agent_api::NginxAgentApi {
|
||||
&self.nginx_agent_api_mock
|
||||
}
|
||||
}
|
||||
329
public/agent-client/src/apis/nginx_agent_api.rs
Normal file
329
public/agent-client/src/apis/nginx_agent_api.rs
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* yanpm-agent
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1.0
|
||||
*
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
use super::{configuration, Error};
|
||||
use crate::apis::ContentType;
|
||||
use crate::{apis::ResponseContent, models};
|
||||
use async_trait::async_trait;
|
||||
#[cfg(feature = "mockall")]
|
||||
use mockall::automock;
|
||||
use reqwest;
|
||||
use serde::{de::Error as _, Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg_attr(feature = "mockall", automock)]
|
||||
#[async_trait]
|
||||
pub trait NginxAgentApi: Send + Sync {
|
||||
/// GET /status
|
||||
///
|
||||
///
|
||||
async fn status(&self) -> Result<ResponseContent<StatusSuccess>, Error<StatusError>>;
|
||||
|
||||
/// POST /validate
|
||||
///
|
||||
///
|
||||
async fn validate(
|
||||
&self,
|
||||
params: ValidateParams,
|
||||
) -> Result<ResponseContent<ValidateSuccess>, Error<ValidateError>>;
|
||||
|
||||
/// POST /validate_and_reload
|
||||
///
|
||||
///
|
||||
async fn validate_and_reload(
|
||||
&self,
|
||||
params: ValidateAndReloadParams,
|
||||
) -> Result<ResponseContent<ValidateAndReloadSuccess>, Error<ValidateAndReloadError>>;
|
||||
|
||||
/// POST /write_config
|
||||
///
|
||||
///
|
||||
async fn write_config(
|
||||
&self,
|
||||
params: WriteConfigParams,
|
||||
) -> Result<ResponseContent<WriteConfigSuccess>, Error<WriteConfigError>>;
|
||||
}
|
||||
|
||||
pub struct NginxAgentApiClient {
|
||||
configuration: Arc<configuration::Configuration>,
|
||||
}
|
||||
|
||||
impl NginxAgentApiClient {
|
||||
pub fn new(configuration: Arc<configuration::Configuration>) -> Self {
|
||||
Self { configuration }
|
||||
}
|
||||
}
|
||||
|
||||
/// struct for passing parameters to the method [`NginxAgentApi::validate`]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ValidateParams {
|
||||
pub validate_body: models::ValidateBody,
|
||||
}
|
||||
|
||||
/// struct for passing parameters to the method [`NginxAgentApi::validate_and_reload`]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ValidateAndReloadParams {
|
||||
pub validate_and_reload_body: models::ValidateAndReloadBody,
|
||||
}
|
||||
|
||||
/// struct for passing parameters to the method [`NginxAgentApi::write_config`]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WriteConfigParams {
|
||||
pub write_config_body: models::WriteConfigBody,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl NginxAgentApi for NginxAgentApiClient {
|
||||
async fn status(&self) -> Result<ResponseContent<StatusSuccess>, Error<StatusError>> {
|
||||
let local_var_configuration = &self.configuration;
|
||||
|
||||
let local_var_client = &local_var_configuration.client;
|
||||
|
||||
let local_var_uri_str = format!("{}/status", local_var_configuration.base_path);
|
||||
let mut local_var_req_builder =
|
||||
local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
|
||||
|
||||
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
|
||||
local_var_req_builder = local_var_req_builder
|
||||
.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
|
||||
}
|
||||
|
||||
let local_var_req = local_var_req_builder.build()?;
|
||||
let local_var_resp = local_var_client.execute(local_var_req).await?;
|
||||
|
||||
let local_var_status = local_var_resp.status();
|
||||
let local_var_content = local_var_resp.text().await?;
|
||||
|
||||
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
|
||||
let local_var_entity: Option<StatusSuccess> =
|
||||
serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_result = ResponseContent {
|
||||
status: local_var_status,
|
||||
content: local_var_content,
|
||||
entity: local_var_entity,
|
||||
};
|
||||
Ok(local_var_result)
|
||||
} else {
|
||||
let local_var_entity: Option<StatusError> =
|
||||
serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_error = ResponseContent {
|
||||
status: local_var_status,
|
||||
content: local_var_content,
|
||||
entity: local_var_entity,
|
||||
};
|
||||
Err(Error::ResponseError(local_var_error))
|
||||
}
|
||||
}
|
||||
|
||||
async fn validate(
|
||||
&self,
|
||||
params: ValidateParams,
|
||||
) -> Result<ResponseContent<ValidateSuccess>, Error<ValidateError>> {
|
||||
let ValidateParams { validate_body } = params;
|
||||
|
||||
let local_var_configuration = &self.configuration;
|
||||
|
||||
let local_var_client = &local_var_configuration.client;
|
||||
|
||||
let local_var_uri_str = format!("{}/validate", local_var_configuration.base_path);
|
||||
let mut local_var_req_builder =
|
||||
local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
|
||||
|
||||
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
|
||||
local_var_req_builder = local_var_req_builder
|
||||
.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
|
||||
}
|
||||
local_var_req_builder = local_var_req_builder.json(&validate_body);
|
||||
|
||||
let local_var_req = local_var_req_builder.build()?;
|
||||
let local_var_resp = local_var_client.execute(local_var_req).await?;
|
||||
|
||||
let local_var_status = local_var_resp.status();
|
||||
let local_var_content = local_var_resp.text().await?;
|
||||
|
||||
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
|
||||
let local_var_entity: Option<ValidateSuccess> =
|
||||
serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_result = ResponseContent {
|
||||
status: local_var_status,
|
||||
content: local_var_content,
|
||||
entity: local_var_entity,
|
||||
};
|
||||
Ok(local_var_result)
|
||||
} else {
|
||||
let local_var_entity: Option<ValidateError> =
|
||||
serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_error = ResponseContent {
|
||||
status: local_var_status,
|
||||
content: local_var_content,
|
||||
entity: local_var_entity,
|
||||
};
|
||||
Err(Error::ResponseError(local_var_error))
|
||||
}
|
||||
}
|
||||
|
||||
async fn validate_and_reload(
|
||||
&self,
|
||||
params: ValidateAndReloadParams,
|
||||
) -> Result<ResponseContent<ValidateAndReloadSuccess>, Error<ValidateAndReloadError>> {
|
||||
let ValidateAndReloadParams {
|
||||
validate_and_reload_body,
|
||||
} = params;
|
||||
|
||||
let local_var_configuration = &self.configuration;
|
||||
|
||||
let local_var_client = &local_var_configuration.client;
|
||||
|
||||
let local_var_uri_str =
|
||||
format!("{}/validate_and_reload", local_var_configuration.base_path);
|
||||
let mut local_var_req_builder =
|
||||
local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
|
||||
|
||||
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
|
||||
local_var_req_builder = local_var_req_builder
|
||||
.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
|
||||
}
|
||||
local_var_req_builder = local_var_req_builder.json(&validate_and_reload_body);
|
||||
|
||||
let local_var_req = local_var_req_builder.build()?;
|
||||
let local_var_resp = local_var_client.execute(local_var_req).await?;
|
||||
|
||||
let local_var_status = local_var_resp.status();
|
||||
let local_var_content = local_var_resp.text().await?;
|
||||
|
||||
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
|
||||
let local_var_entity: Option<ValidateAndReloadSuccess> =
|
||||
serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_result = ResponseContent {
|
||||
status: local_var_status,
|
||||
content: local_var_content,
|
||||
entity: local_var_entity,
|
||||
};
|
||||
Ok(local_var_result)
|
||||
} else {
|
||||
let local_var_entity: Option<ValidateAndReloadError> =
|
||||
serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_error = ResponseContent {
|
||||
status: local_var_status,
|
||||
content: local_var_content,
|
||||
entity: local_var_entity,
|
||||
};
|
||||
Err(Error::ResponseError(local_var_error))
|
||||
}
|
||||
}
|
||||
|
||||
async fn write_config(
|
||||
&self,
|
||||
params: WriteConfigParams,
|
||||
) -> Result<ResponseContent<WriteConfigSuccess>, Error<WriteConfigError>> {
|
||||
let WriteConfigParams { write_config_body } = params;
|
||||
|
||||
let local_var_configuration = &self.configuration;
|
||||
|
||||
let local_var_client = &local_var_configuration.client;
|
||||
|
||||
let local_var_uri_str = format!("{}/write_config", local_var_configuration.base_path);
|
||||
let mut local_var_req_builder =
|
||||
local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
|
||||
|
||||
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
|
||||
local_var_req_builder = local_var_req_builder
|
||||
.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
|
||||
}
|
||||
local_var_req_builder = local_var_req_builder.json(&write_config_body);
|
||||
|
||||
let local_var_req = local_var_req_builder.build()?;
|
||||
let local_var_resp = local_var_client.execute(local_var_req).await?;
|
||||
|
||||
let local_var_status = local_var_resp.status();
|
||||
let local_var_content = local_var_resp.text().await?;
|
||||
|
||||
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
|
||||
let local_var_entity: Option<WriteConfigSuccess> =
|
||||
serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_result = ResponseContent {
|
||||
status: local_var_status,
|
||||
content: local_var_content,
|
||||
entity: local_var_entity,
|
||||
};
|
||||
Ok(local_var_result)
|
||||
} else {
|
||||
let local_var_entity: Option<WriteConfigError> =
|
||||
serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_error = ResponseContent {
|
||||
status: local_var_status,
|
||||
content: local_var_content,
|
||||
entity: local_var_entity,
|
||||
};
|
||||
Err(Error::ResponseError(local_var_error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// struct for typed successes of method [`NginxAgentApi::status`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum StatusSuccess {
|
||||
Status200(models::StatusResp),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed successes of method [`NginxAgentApi::validate`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValidateSuccess {
|
||||
Status200(serde_json::Value),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed successes of method [`NginxAgentApi::validate_and_reload`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValidateAndReloadSuccess {
|
||||
Status200(models::ValidateAndReloadResp),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed successes of method [`NginxAgentApi::write_config`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum WriteConfigSuccess {
|
||||
Status200(),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`NginxAgentApi::status`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum StatusError {
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`NginxAgentApi::validate`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValidateError {
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`NginxAgentApi::validate_and_reload`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValidateAndReloadError {
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`NginxAgentApi::write_config`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum WriteConfigError {
|
||||
Status500(serde_json::Value),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
280
public/agent-client/src/apis/tag_nginxtag_api.rs
Normal file
280
public/agent-client/src/apis/tag_nginxtag_api.rs
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* yanpm-agent
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1.0
|
||||
*
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
|
||||
use async_trait::async_trait;
|
||||
#[cfg(feature = "mockall")]
|
||||
use mockall::automock;
|
||||
use reqwest;
|
||||
use std::sync::Arc;
|
||||
use serde::{Deserialize, Serialize, de::Error as _};
|
||||
use crate::{apis::ResponseContent, models};
|
||||
use super::{Error, configuration};
|
||||
use crate::apis::ContentType;
|
||||
|
||||
#[cfg_attr(feature = "mockall", automock)]
|
||||
#[async_trait]
|
||||
pub trait TagNginxtagApi: Send + Sync {
|
||||
|
||||
/// GET /status
|
||||
///
|
||||
///
|
||||
async fn status(&self, ) -> Result<ResponseContent<StatusSuccess>, Error<StatusError>>;
|
||||
|
||||
/// POST /validate
|
||||
///
|
||||
///
|
||||
async fn validate(&self, params: ValidateParams ) -> Result<ResponseContent<ValidateSuccess>, Error<ValidateError>>;
|
||||
|
||||
/// POST /validate_and_reload
|
||||
///
|
||||
///
|
||||
async fn validate_and_reload(&self, params: ValidateAndReloadParams ) -> Result<ResponseContent<ValidateAndReloadSuccess>, Error<ValidateAndReloadError>>;
|
||||
|
||||
/// POST /write_config
|
||||
///
|
||||
///
|
||||
async fn write_config(&self, params: WriteConfigParams ) -> Result<ResponseContent<WriteConfigSuccess>, Error<WriteConfigError>>;
|
||||
}
|
||||
|
||||
pub struct TagNginxtagApiClient {
|
||||
configuration: Arc<configuration::Configuration>
|
||||
}
|
||||
|
||||
impl TagNginxtagApiClient {
|
||||
pub fn new(configuration: Arc<configuration::Configuration>) -> Self {
|
||||
Self { configuration }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// struct for passing parameters to the method [`TagNginxtagApi::validate`]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ValidateParams {
|
||||
pub validate_body: models::ValidateBody
|
||||
}
|
||||
|
||||
/// struct for passing parameters to the method [`TagNginxtagApi::validate_and_reload`]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ValidateAndReloadParams {
|
||||
pub validate_and_reload_body: models::ValidateAndReloadBody
|
||||
}
|
||||
|
||||
/// struct for passing parameters to the method [`TagNginxtagApi::write_config`]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WriteConfigParams {
|
||||
pub write_config_body: models::WriteConfigBody
|
||||
}
|
||||
|
||||
|
||||
#[async_trait]
|
||||
impl TagNginxtagApi for TagNginxtagApiClient {
|
||||
async fn status(&self, ) -> Result<ResponseContent<StatusSuccess>, Error<StatusError>> {
|
||||
|
||||
|
||||
let local_var_configuration = &self.configuration;
|
||||
|
||||
let local_var_client = &local_var_configuration.client;
|
||||
|
||||
let local_var_uri_str = format!("{}/status", local_var_configuration.base_path);
|
||||
let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
|
||||
|
||||
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
|
||||
local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
|
||||
}
|
||||
|
||||
let local_var_req = local_var_req_builder.build()?;
|
||||
let local_var_resp = local_var_client.execute(local_var_req).await?;
|
||||
|
||||
let local_var_status = local_var_resp.status();
|
||||
let local_var_content = local_var_resp.text().await?;
|
||||
|
||||
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
|
||||
let local_var_entity: Option<StatusSuccess> = serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_result = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
|
||||
Ok(local_var_result)
|
||||
} else {
|
||||
let local_var_entity: Option<StatusError> = serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
|
||||
Err(Error::ResponseError(local_var_error))
|
||||
}
|
||||
}
|
||||
|
||||
async fn validate(&self, params: ValidateParams ) -> Result<ResponseContent<ValidateSuccess>, Error<ValidateError>> {
|
||||
|
||||
let ValidateParams {
|
||||
validate_body,
|
||||
} = params;
|
||||
|
||||
|
||||
let local_var_configuration = &self.configuration;
|
||||
|
||||
let local_var_client = &local_var_configuration.client;
|
||||
|
||||
let local_var_uri_str = format!("{}/validate", local_var_configuration.base_path);
|
||||
let mut local_var_req_builder = local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
|
||||
|
||||
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
|
||||
local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
|
||||
}
|
||||
local_var_req_builder = local_var_req_builder.json(&validate_body);
|
||||
|
||||
let local_var_req = local_var_req_builder.build()?;
|
||||
let local_var_resp = local_var_client.execute(local_var_req).await?;
|
||||
|
||||
let local_var_status = local_var_resp.status();
|
||||
let local_var_content = local_var_resp.text().await?;
|
||||
|
||||
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
|
||||
let local_var_entity: Option<ValidateSuccess> = serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_result = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
|
||||
Ok(local_var_result)
|
||||
} else {
|
||||
let local_var_entity: Option<ValidateError> = serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
|
||||
Err(Error::ResponseError(local_var_error))
|
||||
}
|
||||
}
|
||||
|
||||
async fn validate_and_reload(&self, params: ValidateAndReloadParams ) -> Result<ResponseContent<ValidateAndReloadSuccess>, Error<ValidateAndReloadError>> {
|
||||
|
||||
let ValidateAndReloadParams {
|
||||
validate_and_reload_body,
|
||||
} = params;
|
||||
|
||||
|
||||
let local_var_configuration = &self.configuration;
|
||||
|
||||
let local_var_client = &local_var_configuration.client;
|
||||
|
||||
let local_var_uri_str = format!("{}/validate_and_reload", local_var_configuration.base_path);
|
||||
let mut local_var_req_builder = local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
|
||||
|
||||
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
|
||||
local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
|
||||
}
|
||||
local_var_req_builder = local_var_req_builder.json(&validate_and_reload_body);
|
||||
|
||||
let local_var_req = local_var_req_builder.build()?;
|
||||
let local_var_resp = local_var_client.execute(local_var_req).await?;
|
||||
|
||||
let local_var_status = local_var_resp.status();
|
||||
let local_var_content = local_var_resp.text().await?;
|
||||
|
||||
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
|
||||
let local_var_entity: Option<ValidateAndReloadSuccess> = serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_result = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
|
||||
Ok(local_var_result)
|
||||
} else {
|
||||
let local_var_entity: Option<ValidateAndReloadError> = serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
|
||||
Err(Error::ResponseError(local_var_error))
|
||||
}
|
||||
}
|
||||
|
||||
async fn write_config(&self, params: WriteConfigParams ) -> Result<ResponseContent<WriteConfigSuccess>, Error<WriteConfigError>> {
|
||||
|
||||
let WriteConfigParams {
|
||||
write_config_body,
|
||||
} = params;
|
||||
|
||||
|
||||
let local_var_configuration = &self.configuration;
|
||||
|
||||
let local_var_client = &local_var_configuration.client;
|
||||
|
||||
let local_var_uri_str = format!("{}/write_config", local_var_configuration.base_path);
|
||||
let mut local_var_req_builder = local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
|
||||
|
||||
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
|
||||
local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
|
||||
}
|
||||
local_var_req_builder = local_var_req_builder.json(&write_config_body);
|
||||
|
||||
let local_var_req = local_var_req_builder.build()?;
|
||||
let local_var_resp = local_var_client.execute(local_var_req).await?;
|
||||
|
||||
let local_var_status = local_var_resp.status();
|
||||
let local_var_content = local_var_resp.text().await?;
|
||||
|
||||
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
|
||||
let local_var_entity: Option<WriteConfigSuccess> = serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_result = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
|
||||
Ok(local_var_result)
|
||||
} else {
|
||||
let local_var_entity: Option<WriteConfigError> = serde_json::from_str(&local_var_content).ok();
|
||||
let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
|
||||
Err(Error::ResponseError(local_var_error))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// struct for typed successes of method [`TagNginxtagApi::status`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum StatusSuccess {
|
||||
Status200(models::StatusResp),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed successes of method [`TagNginxtagApi::validate`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValidateSuccess {
|
||||
Status200(serde_json::Value),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed successes of method [`TagNginxtagApi::validate_and_reload`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValidateAndReloadSuccess {
|
||||
Status200(models::ValidateAndReloadResp),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed successes of method [`TagNginxtagApi::write_config`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum WriteConfigSuccess {
|
||||
Status200(),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`TagNginxtagApi::status`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum StatusError {
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`TagNginxtagApi::validate`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValidateError {
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`TagNginxtagApi::validate_and_reload`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValidateAndReloadError {
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`TagNginxtagApi::write_config`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum WriteConfigError {
|
||||
Status500(serde_json::Value),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
10
public/agent-client/src/lib.rs
Normal file
10
public/agent-client/src/lib.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
#![allow(unused_imports)]
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate serde_repr;
|
||||
extern crate url;
|
||||
|
||||
pub mod apis;
|
||||
pub mod models;
|
||||
10
public/agent-client/src/models/mod.rs
Normal file
10
public/agent-client/src/models/mod.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
pub mod status_resp;
|
||||
pub use self::status_resp::StatusResp;
|
||||
pub mod validate_and_reload_body;
|
||||
pub use self::validate_and_reload_body::ValidateAndReloadBody;
|
||||
pub mod validate_and_reload_resp;
|
||||
pub use self::validate_and_reload_resp::ValidateAndReloadResp;
|
||||
pub mod validate_body;
|
||||
pub use self::validate_body::ValidateBody;
|
||||
pub mod write_config_body;
|
||||
pub use self::write_config_body::WriteConfigBody;
|
||||
24
public/agent-client/src/models/status_resp.rs
Normal file
24
public/agent-client/src/models/status_resp.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* yanpm-agent
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1.0
|
||||
*
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
use crate::models;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct StatusResp {
|
||||
#[serde(rename = "ok")]
|
||||
pub ok: bool,
|
||||
}
|
||||
|
||||
impl StatusResp {
|
||||
pub fn new(ok: bool) -> StatusResp {
|
||||
StatusResp { ok }
|
||||
}
|
||||
}
|
||||
29
public/agent-client/src/models/validate_and_reload_body.rs
Normal file
29
public/agent-client/src/models/validate_and_reload_body.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* yanpm-agent
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1.0
|
||||
*
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
use crate::models;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ValidateAndReloadBody {
|
||||
#[serde(rename = "config_name")]
|
||||
pub config_name: String,
|
||||
#[serde(rename = "timestamp")]
|
||||
pub timestamp: i64,
|
||||
}
|
||||
|
||||
impl ValidateAndReloadBody {
|
||||
pub fn new(config_name: String, timestamp: i64) -> ValidateAndReloadBody {
|
||||
ValidateAndReloadBody {
|
||||
config_name,
|
||||
timestamp,
|
||||
}
|
||||
}
|
||||
}
|
||||
26
public/agent-client/src/models/validate_and_reload_resp.rs
Normal file
26
public/agent-client/src/models/validate_and_reload_resp.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* yanpm-agent
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1.0
|
||||
*
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
use crate::models;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ValidateAndReloadResp {
|
||||
#[serde(rename = "rc")]
|
||||
pub rc: i32,
|
||||
#[serde(rename = "ro")]
|
||||
pub ro: String,
|
||||
}
|
||||
|
||||
impl ValidateAndReloadResp {
|
||||
pub fn new(rc: i32, ro: String) -> ValidateAndReloadResp {
|
||||
ValidateAndReloadResp { rc, ro }
|
||||
}
|
||||
}
|
||||
29
public/agent-client/src/models/validate_body.rs
Normal file
29
public/agent-client/src/models/validate_body.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* yanpm-agent
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1.0
|
||||
*
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
use crate::models;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ValidateBody {
|
||||
#[serde(rename = "config_name")]
|
||||
pub config_name: String,
|
||||
#[serde(rename = "timestamp")]
|
||||
pub timestamp: i64,
|
||||
}
|
||||
|
||||
impl ValidateBody {
|
||||
pub fn new(config_name: String, timestamp: i64) -> ValidateBody {
|
||||
ValidateBody {
|
||||
config_name,
|
||||
timestamp,
|
||||
}
|
||||
}
|
||||
}
|
||||
32
public/agent-client/src/models/write_config_body.rs
Normal file
32
public/agent-client/src/models/write_config_body.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* yanpm-agent
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1.0
|
||||
*
|
||||
* Generated by: https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
use crate::models;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct WriteConfigBody {
|
||||
#[serde(rename = "config_name")]
|
||||
pub config_name: String,
|
||||
#[serde(rename = "content")]
|
||||
pub content: String,
|
||||
#[serde(rename = "timestamp")]
|
||||
pub timestamp: i64,
|
||||
}
|
||||
|
||||
impl WriteConfigBody {
|
||||
pub fn new(config_name: String, content: String, timestamp: i64) -> WriteConfigBody {
|
||||
WriteConfigBody {
|
||||
config_name,
|
||||
content,
|
||||
timestamp,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user