From 6ccb9d841d9c81a585bc502b96c07d58b52104c7 Mon Sep 17 00:00:00 2001 From: "R. Tyler Croy" Date: Sun, 22 Nov 2020 10:39:16 -0800 Subject: [PATCH] Sketch out the RunWorkload for the local-orchestrator service --- Cargo.lock | 4 ++ Makefile | 4 +- services/local-orchestrator/Cargo.toml | 4 ++ services/local-orchestrator/apispec.yml | 55 ++++++++++++++++++++++++- services/local-orchestrator/src/main.rs | 22 ++++++++++ services/parser/apispec.yml | 8 ++-- 6 files changed, 90 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6257252..8da3721 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1606,8 +1606,12 @@ version = "0.1.0" dependencies = [ "async-std", "log", + "otto-models", "pretty_env_logger 0.4.0", + "serde 1.0.117", + "serde_json", "tide 0.15.0", + "uuid", ] [[package]] diff --git a/Makefile b/Makefile index 059d99a..2baac14 100644 --- a/Makefile +++ b/Makefile @@ -21,8 +21,8 @@ steps: release done; apispecs: - schemathesis run ./services/parser/apispec.yml --base-url=http://localhost:7672 --checks all - schemathesis run ./services/local-orchestrator/apispec.yml --base-url=http://localhost:7673 --checks all + schemathesis run ./services/local-orchestrator/apispec.yml --base-url=http://localhost:7673 --checks all --hypothesis-suppress-health-check too_slow + schemathesis run ./services/parser/apispec.yml --base-url=http://localhost:7672 --checks all --hypothesis-suppress-health-check too_slow test: contrib/shunit2/shunit2 ## Run the acceptance tests for steps set -e diff --git a/services/local-orchestrator/Cargo.toml b/services/local-orchestrator/Cargo.toml index e181234..baa685f 100644 --- a/services/local-orchestrator/Cargo.toml +++ b/services/local-orchestrator/Cargo.toml @@ -7,5 +7,9 @@ edition = "2018" [dependencies] async-std = { version = "~1.7", features = ["attributes"]} log = "~0.4.11" +otto-models = { path = "../../models" } pretty_env_logger = "~0.4.0" +serde = {version = "~1.0.117", features = ["rc", "derive"]} +serde_json = "~1.0.59" +uuid = { version = "~0.8.1", features = ["v4", "serde"]} tide = "~0.15.0" diff --git a/services/local-orchestrator/apispec.yml b/services/local-orchestrator/apispec.yml index 625557c..6f410fe 100644 --- a/services/local-orchestrator/apispec.yml +++ b/services/local-orchestrator/apispec.yml @@ -30,5 +30,58 @@ paths: '200': description: 'A successful healthcheck' content: - application/json: {} + 'application/json': {} + '/v1/run': + post: + operationId: RunWorkload + description: | + The primary interface for the orchestrator which allows external services to + provision an agent to run the specified workload. + This endpoint is not _synchronous_ insofar that it will enqueue the + workload. It will not block until the workload has completed execution + for hopefully obvious reasons. + requestBody: + required: true + content: + 'application/json': + schema: + $ref: '#/components/schemas/RunWorkloadRequest' + responses: + '200': + description: 'Successfully enqueued the workload with the orchestrator' + + '422': + description: 'Unprocessable data, usually not JSON or not UTF-6 encoded' + +components: + schemas: + RunWorkloadRequest: + description: | + The primary APi payload for the orchestrator, which includes the workloads + that should be provisioned and executed by the orchestrator. + + THe list of contexts should _only_ those that can be safely executed by one + agent in sequence. + type: object + required: + - pipeline + - contexts + properties: + pipeline: + type: string + format: uuid + contexts: + type: array + example: + pipeline: '9edc4483-a78a-480f-8e06-2726db1ddf24' + contexts: + - uuid: '8109f601-12e8-4621-96c6-11baff409d93' + properties: + name: 'Build' + steps: + - uuid: '6193b9b1-c6be-4c18-9bb8-1aeead5e7d14' + context: '8109f601-12e8-4621-96c6-11baff409d93' + symbol: 'sh' + parameters: + - 'ls' diff --git a/services/local-orchestrator/src/main.rs b/services/local-orchestrator/src/main.rs index 326f8fb..13b6654 100644 --- a/services/local-orchestrator/src/main.rs +++ b/services/local-orchestrator/src/main.rs @@ -1,7 +1,16 @@ /* * The local orchestrator doesn't do much */ +use log::*; +use serde::Deserialize; use tide::Request; +use uuid::Uuid; + +#[derive(Clone, Debug, Deserialize)] +struct RunWorkload { + pipeline: Uuid, + contexts: Vec, +} async fn healthcheck(_req: Request<()>) -> tide::Result { Ok(tide::Response::builder(200) @@ -10,6 +19,18 @@ async fn healthcheck(_req: Request<()>) -> tide::Result { .build()) } +async fn run_workload(mut req: Request<()>) -> tide::Result { + let run: RunWorkload = req.body_json().await?; + debug!("Received RunWorkload: {:#?}", run); + + // TODO: do something actually useful :D + + Ok(tide::Response::builder(200) + .body("{}") + .content_type("application/json") + .build()) +} + #[async_std::main] async fn main() -> std::io::Result<()> { use std::{env, net::TcpListener, os::unix::io::FromRawFd}; @@ -17,6 +38,7 @@ async fn main() -> std::io::Result<()> { let mut app = tide::new(); app.at("/health").get(healthcheck); + app.at("/v1/run").post(run_workload); if let Some(fd) = env::var("LISTEN_FD").ok().and_then(|fd| fd.parse().ok()) { app.listen(unsafe { TcpListener::from_raw_fd(fd) }).await?; diff --git a/services/parser/apispec.yml b/services/parser/apispec.yml index 1b6f96a..a217902 100644 --- a/services/parser/apispec.yml +++ b/services/parser/apispec.yml @@ -31,7 +31,7 @@ paths: '200': description: 'A successful healthcheck' content: - application/json: {} + 'application/json': {} '/v1/parse': post: @@ -44,7 +44,7 @@ paths: description: 'A string payload in the Otto Pipeline syntax' required: true content: - text/plain: + 'text/plain': schema: type: string examples: @@ -64,13 +64,13 @@ paths: '200': description: 'Successfully parsed' content: - application/json: + 'application/json': schema: $ref: '#/components/schemas/ParsePipelineResponse' '400': description: 'Failed to parse the pipeline for some reason' content: - application/json: + 'application/json': schema: $ref: '#/components/schemas/ParsePipelineFailure' '422':