diff --git a/lib/circles/actions/openapi.yaml b/lib/circles/actions/openapi.yaml new file mode 100644 index 00000000..3e5e9d72 --- /dev/null +++ b/lib/circles/actions/openapi.yaml @@ -0,0 +1,675 @@ +openapi: 3.1.0 +info: + title: HeroLib Circles API + description: API for managing jobs and actions in the HeroLib Circles module + version: 1.0.0 + contact: + name: FreeFlow Universe + url: https://github.com/freeflowuniverse/herolib + +servers: + - url: /api/v1 + description: Default API server + +paths: + /jobs: + get: + summary: List all jobs + description: Returns all job IDs in the system + operationId: listJobs + tags: + - jobs + responses: + '200': + description: A list of job IDs + content: + application/json: + schema: + type: array + items: + type: integer + format: int32 + examples: + listJobsExample: + value: [1, 2, 3, 4, 5] + '500': + $ref: '#/components/responses/InternalServerError' + post: + summary: Create a new job + description: Creates a new job in the system + operationId: createJob + tags: + - jobs + requestBody: + description: Job object to be created + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/JobCreate' + examples: + createJobExample: + value: + agents: ["agent1pubkey", "agent2pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "start" + params: + id: "10" + name: "test-vm" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + dependencies: [] + responses: + '201': + description: Job created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + '400': + $ref: '#/components/responses/BadRequest' + '500': + $ref: '#/components/responses/InternalServerError' + + /jobs/all: + get: + summary: Get all jobs + description: Returns all jobs in the system + operationId: getAllJobs + tags: + - jobs + responses: + '200': + description: A list of jobs + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Job' + examples: + getAllJobsExample: + value: + - id: 1 + guid: "job-guid-1" + agents: ["agent1pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "start" + params: + id: "10" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + status: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:25:45Z" + status: "ok" + dependencies: [] + - id: 2 + guid: "job-guid-2" + agents: ["agent2pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "stop" + params: + id: "11" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + status: + guid: "job-guid-2" + created: "2025-03-16T14:10:30Z" + start: "2025-03-16T14:11:00Z" + end: "2025-03-16T14:12:45Z" + status: "ok" + dependencies: [] + '500': + $ref: '#/components/responses/InternalServerError' + + /jobs/{id}: + get: + summary: Get a job by ID + description: Returns a job by its numeric ID + operationId: getJobById + tags: + - jobs + parameters: + - name: id + in: path + description: Job ID + required: true + schema: + type: integer + format: int32 + responses: + '200': + description: Job found + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + examples: + getJobByIdExample: + value: + id: 1 + guid: "job-guid-1" + agents: ["agent1pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "start" + params: + id: "10" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + status: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:25:45Z" + status: "ok" + dependencies: [] + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + put: + summary: Update a job + description: Updates an existing job + operationId: updateJob + tags: + - jobs + parameters: + - name: id + in: path + description: Job ID + required: true + schema: + type: integer + format: int32 + requestBody: + description: Job object to update + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + examples: + updateJobExample: + value: + id: 1 + guid: "job-guid-1" + agents: ["agent1pubkey", "agent3pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "restart" + params: + id: "10" + force: "true" + timeout_schedule: 30 + timeout: 1800 + log: true + ignore_error: true + ignore_error_codes: [404] + debug: true + retry: 2 + status: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:25:45Z" + status: "ok" + dependencies: [] + responses: + '200': + description: Job updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + '400': + $ref: '#/components/responses/BadRequest' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + delete: + summary: Delete a job + description: Deletes a job by its ID + operationId: deleteJob + tags: + - jobs + parameters: + - name: id + in: path + description: Job ID + required: true + schema: + type: integer + format: int32 + responses: + '204': + description: Job deleted successfully + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + + /jobs/guid/{guid}: + get: + summary: Get a job by GUID + description: Returns a job by its GUID + operationId: getJobByGuid + tags: + - jobs + parameters: + - name: guid + in: path + description: Job GUID + required: true + schema: + type: string + responses: + '200': + description: Job found + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + examples: + getJobByGuidExample: + value: + id: 1 + guid: "job-guid-1" + agents: ["agent1pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "start" + params: + id: "10" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + status: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:25:45Z" + status: "ok" + dependencies: [] + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + delete: + summary: Delete a job by GUID + description: Deletes a job by its GUID + operationId: deleteJobByGuid + tags: + - jobs + parameters: + - name: guid + in: path + description: Job GUID + required: true + schema: + type: string + responses: + '204': + description: Job deleted successfully + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + + /jobs/guid/{guid}/status: + put: + summary: Update job status + description: Updates the status of a job by its GUID + operationId: updateJobStatus + tags: + - jobs + parameters: + - name: guid + in: path + description: Job GUID + required: true + schema: + type: string + requestBody: + description: New job status + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/JobStatus' + examples: + updateJobStatusExample: + value: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:30:45Z" + status: "running" + responses: + '200': + description: Job status updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + '400': + $ref: '#/components/responses/BadRequest' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + +components: + schemas: + Job: + type: object + required: + - id + - guid + - agents + - source + - actor + - action + - status + properties: + id: + type: integer + format: int32 + description: Unique numeric ID for the job + guid: + type: string + description: Unique ID for the job + agents: + type: array + description: The public keys of the agent(s) which will execute the command + items: + type: string + source: + type: string + description: Public key from the agent who asked for the job + circle: + type: string + description: Circle in which the job is organized + default: default + context: + type: string + description: High level context in which actors will execute the work inside a circle + default: default + actor: + type: string + description: The actor that will execute the job (e.g. vm_manager) + action: + type: string + description: The action to be executed (e.g. start) + params: + type: object + description: Parameters for the job (e.g. id:10) + additionalProperties: + type: string + timeout_schedule: + type: integer + format: int32 + description: Timeout before the job is picked up (in seconds) + default: 60 + timeout: + type: integer + format: int32 + description: Timeout for job execution (in seconds) + default: 3600 + log: + type: boolean + description: Whether to log job execution + default: true + ignore_error: + type: boolean + description: If true, errors will be ignored and not reported + default: false + ignore_error_codes: + type: array + description: Error codes to ignore + items: + type: integer + format: int32 + debug: + type: boolean + description: If true, more context will be provided for debugging + default: false + retry: + type: integer + format: int32 + description: Number of retries for the job + default: 0 + status: + $ref: '#/components/schemas/JobStatus' + dependencies: + type: array + description: Jobs that must be completed before this job can execute + items: + $ref: '#/components/schemas/JobDependency' + + JobCreate: + type: object + required: + - agents + - source + - actor + - action + properties: + agents: + type: array + description: The public keys of the agent(s) which will execute the command + items: + type: string + source: + type: string + description: Public key from the agent who asked for the job + circle: + type: string + description: Circle in which the job is organized + default: default + context: + type: string + description: High level context in which actors will execute the work inside a circle + default: default + actor: + type: string + description: The actor that will execute the job (e.g. vm_manager) + action: + type: string + description: The action to be executed (e.g. start) + params: + type: object + description: Parameters for the job (e.g. id:10) + additionalProperties: + type: string + timeout_schedule: + type: integer + format: int32 + description: Timeout before the job is picked up (in seconds) + default: 60 + timeout: + type: integer + format: int32 + description: Timeout for job execution (in seconds) + default: 3600 + log: + type: boolean + description: Whether to log job execution + default: true + ignore_error: + type: boolean + description: If true, errors will be ignored and not reported + default: false + ignore_error_codes: + type: array + description: Error codes to ignore + items: + type: integer + format: int32 + debug: + type: boolean + description: If true, more context will be provided for debugging + default: false + retry: + type: integer + format: int32 + description: Number of retries for the job + default: 0 + dependencies: + type: array + description: Jobs that must be completed before this job can execute + items: + $ref: '#/components/schemas/JobDependency' + + JobStatus: + type: object + required: + - guid + - status + properties: + guid: + type: string + description: Unique ID for the job + created: + type: string + format: date-time + description: When the job was created + start: + type: string + format: date-time + description: When the job started or should start + end: + type: string + format: date-time + description: When the job ended + status: + type: string + description: Current status of the job + enum: + - created + - scheduled + - planned + - running + - error + - ok + + JobDependency: + type: object + required: + - guid + properties: + guid: + type: string + description: Unique ID for the dependent job + agents: + type: array + description: The public keys of the agent(s) which can execute the command + items: + type: string + + responses: + BadRequest: + description: Bad request + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + badRequestExample: + value: + code: 400 + message: "Invalid request parameters" + + NotFound: + description: Resource not found + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + notFoundExample: + value: + code: 404 + message: "Job not found" + + InternalServerError: + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" diff --git a/lib/circles/actions/openapi.yaml.new b/lib/circles/actions/openapi.yaml.new new file mode 100644 index 00000000..5aef2e19 --- /dev/null +++ b/lib/circles/actions/openapi.yaml.new @@ -0,0 +1,935 @@ +openapi: 3.1.0 +info: + title: HeroLib Circles API + description: API for managing jobs and actions in the HeroLib Circles module + version: 1.0.0 + contact: + name: FreeFlow Universe + url: https://github.com/freeflowuniverse/herolib + +servers: + - url: /api/v1 + description: Default API server + +paths: + /jobs: + get: + summary: List all jobs + description: Returns all job IDs in the system + operationId: listJobs + tags: + - jobs + responses: + '200': + description: A list of job IDs + content: + application/json: + schema: + type: array + items: + type: integer + format: int32 + examples: + listJobsExample: + value: [1, 2, 3, 4, 5] + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + post: + summary: Create a new job + description: Creates a new job in the system + operationId: createJob + tags: + - jobs + requestBody: + description: Job object to be created + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/JobCreate' + examples: + createJobExample: + value: + agents: ["agent1pubkey", "agent2pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "start" + params: + id: "10" + name: "test-vm" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + dependencies: [] + responses: + '201': + description: Job created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + '400': + description: Bad request + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + badRequestExample: + value: + code: 400 + message: "Invalid request parameters" + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + + /jobs/all: + get: + summary: Get all jobs + description: Returns all jobs in the system + operationId: getAllJobs + tags: + - jobs + responses: + '200': + description: A list of jobs + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Job' + examples: + getAllJobsExample: + value: + - id: 1 + guid: "job-guid-1" + agents: ["agent1pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "start" + params: + id: "10" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + status: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:25:45Z" + status: "ok" + dependencies: [] + - id: 2 + guid: "job-guid-2" + agents: ["agent2pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "stop" + params: + id: "11" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + status: + guid: "job-guid-2" + created: "2025-03-16T14:10:30Z" + start: "2025-03-16T14:11:00Z" + end: "2025-03-16T14:12:45Z" + status: "ok" + dependencies: [] + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + + /jobs/{id}: + get: + summary: Get a job by ID + description: Returns a job by its numeric ID + operationId: getJobById + tags: + - jobs + parameters: + - name: id + in: path + description: Job ID + required: true + schema: + type: integer + format: int32 + responses: + '200': + description: Job found + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + examples: + getJobByIdExample: + value: + id: 1 + guid: "job-guid-1" + agents: ["agent1pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "start" + params: + id: "10" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + status: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:25:45Z" + status: "ok" + dependencies: [] + '404': + description: Resource not found + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + notFoundExample: + value: + code: 404 + message: "Job not found" + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + put: + summary: Update a job + description: Updates an existing job + operationId: updateJob + tags: + - jobs + parameters: + - name: id + in: path + description: Job ID + required: true + schema: + type: integer + format: int32 + requestBody: + description: Job object to update + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + examples: + updateJobExample: + value: + id: 1 + guid: "job-guid-1" + agents: ["agent1pubkey", "agent3pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "restart" + params: + id: "10" + force: "true" + timeout_schedule: 30 + timeout: 1800 + log: true + ignore_error: true + ignore_error_codes: [404] + debug: true + retry: 2 + status: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:25:45Z" + status: "ok" + dependencies: [] + responses: + '200': + description: Job updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + '400': + description: Bad request + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + badRequestExample: + value: + code: 400 + message: "Invalid request parameters" + '404': + description: Resource not found + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + notFoundExample: + value: + code: 404 + message: "Job not found" + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + delete: + summary: Delete a job + description: Deletes a job by its ID + operationId: deleteJob + tags: + - jobs + parameters: + - name: id + in: path + description: Job ID + required: true + schema: + type: integer + format: int32 + responses: + '204': + description: Job deleted successfully + '404': + description: Resource not found + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + notFoundExample: + value: + code: 404 + message: "Job not found" + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + + /jobs/guid/{guid}: + get: + summary: Get a job by GUID + description: Returns a job by its GUID + operationId: getJobByGuid + tags: + - jobs + parameters: + - name: guid + in: path + description: Job GUID + required: true + schema: + type: string + responses: + '200': + description: Job found + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + examples: + getJobByGuidExample: + value: + id: 1 + guid: "job-guid-1" + agents: ["agent1pubkey"] + source: "sourcepubkey" + circle: "default" + context: "default" + actor: "vm_manager" + action: "start" + params: + id: "10" + timeout_schedule: 60 + timeout: 3600 + log: true + ignore_error: false + ignore_error_codes: [] + debug: false + retry: 0 + status: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:25:45Z" + status: "ok" + dependencies: [] + '404': + description: Resource not found + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + notFoundExample: + value: + code: 404 + message: "Job not found" + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + delete: + summary: Delete a job by GUID + description: Deletes a job by its GUID + operationId: deleteJobByGuid + tags: + - jobs + parameters: + - name: guid + in: path + description: Job GUID + required: true + schema: + type: string + responses: + '204': + description: Job deleted successfully + '404': + description: Resource not found + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + notFoundExample: + value: + code: 404 + message: "Job not found" + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + + /jobs/guid/{guid}/status: + put: + summary: Update job status + description: Updates the status of a job by its GUID + operationId: updateJobStatus + tags: + - jobs + parameters: + - name: guid + in: path + description: Job GUID + required: true + schema: + type: string + requestBody: + description: New job status + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/JobStatus' + examples: + updateJobStatusExample: + value: + guid: "job-guid-1" + created: "2025-03-16T13:20:30Z" + start: "2025-03-16T13:21:00Z" + end: "2025-03-16T13:30:45Z" + status: "running" + responses: + '200': + description: Job status updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + '400': + description: Bad request + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + badRequestExample: + value: + code: 400 + message: "Invalid request parameters" + '404': + description: Resource not found + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + notFoundExample: + value: + code: 404 + message: "Job not found" + '500': + description: Internal server error + content: + application/json: + schema: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + examples: + internalServerErrorExample: + value: + code: 500 + message: "Internal server error" + +components: + schemas: + Job: + type: object + required: + - id + - guid + - agents + - source + - actor + - action + - status + properties: + id: + type: integer + format: int32 + description: Unique numeric ID for the job + guid: + type: string + description: Unique ID for the job + agents: + type: array + description: The public keys of the agent(s) which will execute the command + items: + type: string + source: + type: string + description: Public key from the agent who asked for the job + circle: + type: string + description: Circle in which the job is organized + default: default + context: + type: string + description: High level context in which actors will execute the work inside a circle + default: default + actor: + type: string + description: The actor that will execute the job (e.g. vm_manager) + action: + type: string + description: The action to be executed (e.g. start) + params: + type: object + description: Parameters for the job (e.g. id:10) + additionalProperties: + type: string + timeout_schedule: + type: integer + format: int32 + description: Timeout before the job is picked up (in seconds) + default: 60 + timeout: + type: integer + format: int32 + description: Timeout for job execution (in seconds) + default: 3600 + log: + type: boolean + description: Whether to log job execution + default: true + ignore_error: + type: boolean + description: If true, errors will be ignored and not reported + default: false + ignore_error_codes: + type: array + description: Error codes to ignore + items: + type: integer + format: int32 + debug: + type: boolean + description: If true, more context will be provided for debugging + default: false + retry: + type: integer + format: int32 + description: Number of retries for the job + default: 0 + status: + $ref: '#/components/schemas/JobStatus' + dependencies: + type: array + description: Jobs that must be completed before this job can execute + items: + $ref: '#/components/schemas/JobDependency' + + JobCreate: + type: object + required: + - agents + - source + - actor + - action + properties: + agents: + type: array + description: The public keys of the agent(s) which will execute the command + items: + type: string + source: + type: string + description: Public key from the agent who asked for the job + circle: + type: string + description: Circle in which the job is organized + default: default + context: + type: string + description: High level context in which actors will execute the work inside a circle + default: default + actor: + type: string + description: The actor that will execute the job (e.g. vm_manager) + action: + type: string + description: The action to be executed (e.g. start) + params: + type: object + description: Parameters for the job (e.g. id:10) + additionalProperties: + type: string + timeout_schedule: + type: integer + format: int32 + description: Timeout before the job is picked up (in seconds) + default: 60 + timeout: + type: integer + format: int32 + description: Timeout for job execution (in seconds) + default: 3600 + log: + type: boolean + description: Whether to log job execution + default: true + ignore_error: + type: boolean + description: If true, errors will be ignored and not reported + default: false + ignore_error_codes: + type: array + description: Error codes to ignore + items: + type: integer + format: int32 + debug: + type: boolean + description: If true, more context will be provided for debugging + default: false + retry: + type: integer + format: int32 + description: Number of retries for the job + default: 0 + dependencies: + type: array + description: Jobs that must be completed before this job can execute + items: + $ref: '#/components/schemas/JobDependency' + + JobStatus: + type: object + required: + - guid + - status + properties: + guid: + type: string + description: Unique ID for the job + created: + type: string + format: date-time + description: When the job was created + start: + type: string + format: date-time + description: When the job started or should start + end: + type: string + format: date-time + description: When the job ended + status: + type: string + description: Current status of the job + enum: + - created + - scheduled + - planned + - running + - error + - ok + + JobDependency: + type: object + required: + - guid + properties: + guid: + type: string + description: Unique ID for the dependent job + agents: + type: array + description: The public keys of the agent(s) which can execute the command + items: + type: string diff --git a/lib/circles/actions/specs.v b/lib/circles/actions/specs.v new file mode 100644 index 00000000..7d504b8c --- /dev/null +++ b/lib/circles/actions/specs.v @@ -0,0 +1,78 @@ +module actions + +// new creates a new Job instance +pub fn (mut m JobDB) new() Job + +// set adds or updates a job +pub fn (mut m JobDB) set(job Job) !Job + +// get retrieves a job by its ID +pub fn (mut m JobDB) get(id u32) !Job + +// list returns all job IDs +pub fn (mut m JobDB) list() ![]u32 + +// getall returns all jobs +pub fn (mut m JobDB) getall() ![]Job + +// delete removes a job by its ID +pub fn (mut m JobDB) delete(id u32) ! + +// get_by_guid retrieves a job by its GUID +pub fn (mut m JobDB) get_by_guid(guid string) !Job + +// delete_by_guid removes a job by its GUID +pub fn (mut m JobDB) delete_by_guid(guid string) ! + +// update_job_status updates the status of a job +pub fn (mut m JobDB) update_job_status(guid string, new_status JobStatus) !Job + +// Job represents a task to be executed by an agent +pub struct Job { +pub mut: + id u32 // unique numeric id for the job + guid string // unique id for the job + agents []string // the pub key of the agent(s) which will execute the command, only 1 will execute + source string // pubkey from the agent who asked for the job + circle string = 'default' // our digital life is organized in circles + context string = 'default' // is the high level context in which actors will execute the work inside a circle + actor string // e.g. vm_manager + action string // e.g. start + params map[string]string // e.g. id:10 + timeout_schedule u16 = 60 // timeout before its picked up + timeout u16 = 3600 // timeout in sec + log bool = true + ignore_error bool // means if error will just exit and not raise, there will be no error reporting + ignore_error_codes []u16 // of we want to ignore certain error codes + debug bool // if debug will get more context + retry u8 // default there is no debug + status JobStatus + dependencies []JobDependency // will not execute until other jobs are done +} + +// JobStatus represents the current state of a job +pub struct JobStatus { +pub mut: + guid string // unique id for the job + created ourtime.OurTime // when we created the job + start ourtime.OurTime // when the job needs to start + end ourtime.OurTime // when the job ended, can be in error + status Status // current status of the job +} + +// JobDependency represents a dependency on another job +pub struct JobDependency { +pub mut: + guid string // unique id for the job + agents []string // the pub key of the agent(s) which can execute the command +} + +// Status represents the possible states of a job +pub enum Status { + created // initial state + scheduled // job has been scheduled + planned // arrived where actor will execute the job + running // job is currently running + error // job encountered an error + ok // job completed successfully +} diff --git a/lib/circles/core/openapi.yaml b/lib/circles/core/openapi.yaml new file mode 100644 index 00000000..738ca80c --- /dev/null +++ b/lib/circles/core/openapi.yaml @@ -0,0 +1,817 @@ +openapi: 3.1.0 +info: + title: Herolib Circles Core API + description: API for managing Circles, Agents, and Names in the Herolib framework + version: 1.0.0 + +servers: + - url: https://api.example.com/v1 + description: Main API server + +components: + schemas: + # Agent related schemas + AgentState: + type: string + enum: + - ok + - down + - error + - halted + description: Represents the possible states of an agent + + AgentServiceState: + type: string + enum: + - ok + - down + - error + - halted + description: Represents the possible states of an agent service or action + + AgentStatus: + type: object + properties: + guid: + type: string + description: Unique id for the job + timestamp_first: + type: string + format: date-time + description: When agent came online + timestamp_last: + type: string + format: date-time + description: Last time agent let us know that it is working + status: + $ref: '#/components/schemas/AgentState' + required: + - guid + - timestamp_first + - timestamp_last + - status + + AgentServiceAction: + type: object + properties: + action: + type: string + description: Which action + description: + type: string + description: Optional description + params: + type: object + additionalProperties: + type: string + description: Parameters for the action + params_example: + type: object + additionalProperties: + type: string + description: Example parameters + status: + $ref: '#/components/schemas/AgentServiceState' + public: + type: boolean + description: If everyone can use then true, if restricted means only certain people can use + required: + - action + - status + - public + + AgentService: + type: object + properties: + actor: + type: string + description: Name of the actor providing the service + actions: + type: array + items: + $ref: '#/components/schemas/AgentServiceAction' + description: Available actions for this service + description: + type: string + description: Optional description + status: + $ref: '#/components/schemas/AgentServiceState' + public: + type: boolean + description: If everyone can use then true, if restricted means only certain people can use + required: + - actor + - actions + - status + - public + + Agent: + type: object + properties: + id: + type: integer + format: uint32 + description: Unique identifier + pubkey: + type: string + description: Public key using ed25519 + address: + type: string + description: Where we can find the agent + port: + type: integer + format: uint16 + description: Default 9999 + description: + type: string + description: Optional description + status: + $ref: '#/components/schemas/AgentStatus' + services: + type: array + items: + $ref: '#/components/schemas/AgentService' + signature: + type: string + description: Signature as done by private key of $address+$port+$description+$status + required: + - id + - pubkey + - address + - port + - status + - services + - signature + + ServiceParams: + type: object + properties: + actor: + type: string + description: + type: string + + ActionParams: + type: object + properties: + action: + type: string + description: + type: string + + # Circle related schemas + Role: + type: string + enum: + - admin + - stakeholder + - member + - contributor + - guest + description: Represents the role of a member in a circle + + Member: + type: object + properties: + pubkeys: + type: array + items: + type: string + description: Public keys of the member + emails: + type: array + items: + type: string + description: List of emails + name: + type: string + description: Name of the member + description: + type: string + description: Optional description + role: + $ref: '#/components/schemas/Role' + required: + - pubkeys + - emails + - name + - role + + Circle: + type: object + properties: + id: + type: integer + format: uint32 + description: Unique id + name: + type: string + description: Name of the circle + description: + type: string + description: Optional description + members: + type: array + items: + $ref: '#/components/schemas/Member' + description: Members of the circle + required: + - id + - name + - members + + # Name related schemas + RecordType: + type: string + enum: + - a + - aaaa + - cname + - mx + - ns + - ptr + - soa + - srv + - txt + description: Record types for a DNS record + + Record: + type: object + properties: + name: + type: string + description: Name of the record + text: + type: string + category: + $ref: '#/components/schemas/RecordType' + addr: + type: array + items: + type: string + description: Multiple IP addresses for this record + required: + - name + - category + + Name: + type: object + properties: + id: + type: integer + format: uint32 + description: Unique id + domain: + type: string + description: Domain name + description: + type: string + description: Optional description + records: + type: array + items: + $ref: '#/components/schemas/Record' + description: DNS records + admins: + type: array + items: + type: string + description: Public keys of admins who can change it + required: + - id + - domain + - records + +paths: + # Agent endpoints + /agents: + get: + summary: List all agents + description: Returns all agent IDs + operationId: listAgents + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + type: integer + format: uint32 + post: + summary: Create a new agent + description: Creates a new agent + operationId: createAgent + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Agent' + responses: + '201': + description: Agent created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Agent' + + /agents/all: + get: + summary: Get all agents + description: Returns all agents + operationId: getAllAgents + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Agent' + + /agents/{id}: + get: + summary: Get agent by ID + description: Returns a single agent + operationId: getAgentById + parameters: + - name: id + in: path + description: ID of agent to return + required: true + schema: + type: integer + format: uint32 + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Agent' + '404': + description: Agent not found + put: + summary: Update an agent + description: Updates an existing agent + operationId: updateAgent + parameters: + - name: id + in: path + description: ID of agent to update + required: true + schema: + type: integer + format: uint32 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Agent' + responses: + '200': + description: Agent updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Agent' + '404': + description: Agent not found + delete: + summary: Delete an agent + description: Deletes an agent + operationId: deleteAgent + parameters: + - name: id + in: path + description: ID of agent to delete + required: true + schema: + type: integer + format: uint32 + responses: + '204': + description: Agent deleted successfully + '404': + description: Agent not found + + /agents/pubkey/{pubkey}: + get: + summary: Get agent by public key + description: Returns a single agent by its public key + operationId: getAgentByPubkey + parameters: + - name: pubkey + in: path + description: Public key of agent to return + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Agent' + '404': + description: Agent not found + delete: + summary: Delete an agent by public key + description: Deletes an agent by its public key + operationId: deleteAgentByPubkey + parameters: + - name: pubkey + in: path + description: Public key of agent to delete + required: true + schema: + type: string + responses: + '204': + description: Agent deleted successfully + '404': + description: Agent not found + + /agents/pubkey/{pubkey}/status: + put: + summary: Update agent status + description: Updates just the status of an agent + operationId: updateAgentStatus + parameters: + - name: pubkey + in: path + description: Public key of agent to update + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AgentState' + responses: + '200': + description: Agent status updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Agent' + '404': + description: Agent not found + + /agents/pubkeys: + get: + summary: Get all agent public keys + description: Returns all agent public keys + operationId: getAllAgentPubkeys + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + type: string + + /agents/service: + get: + summary: Get agents by service + description: Returns all agents that provide a specific service + operationId: getAgentsByService + parameters: + - name: actor + in: query + description: Actor name + required: true + schema: + type: string + - name: action + in: query + description: Action name + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Agent' + + # Circle endpoints + /circles: + get: + summary: List all circles + description: Returns all circle IDs + operationId: listCircles + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + type: integer + format: uint32 + post: + summary: Create a new circle + description: Creates a new circle + operationId: createCircle + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Circle' + responses: + '201': + description: Circle created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Circle' + + /circles/all: + get: + summary: Get all circles + description: Returns all circles + operationId: getAllCircles + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Circle' + + /circles/{id}: + get: + summary: Get circle by ID + description: Returns a single circle + operationId: getCircleById + parameters: + - name: id + in: path + description: ID of circle to return + required: true + schema: + type: integer + format: uint32 + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Circle' + '404': + description: Circle not found + put: + summary: Update a circle + description: Updates an existing circle + operationId: updateCircle + parameters: + - name: id + in: path + description: ID of circle to update + required: true + schema: + type: integer + format: uint32 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Circle' + responses: + '200': + description: Circle updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Circle' + '404': + description: Circle not found + delete: + summary: Delete a circle + description: Deletes a circle + operationId: deleteCircle + parameters: + - name: id + in: path + description: ID of circle to delete + required: true + schema: + type: integer + format: uint32 + responses: + '204': + description: Circle deleted successfully + '404': + description: Circle not found + + /circles/name/{name}: + get: + summary: Get circle by name + description: Returns a single circle by its name + operationId: getCircleByName + parameters: + - name: name + in: path + description: Name of circle to return + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Circle' + '404': + description: Circle not found + delete: + summary: Delete a circle by name + description: Deletes a circle by its name + operationId: deleteCircleByName + parameters: + - name: name + in: path + description: Name of circle to delete + required: true + schema: + type: string + responses: + '204': + description: Circle deleted successfully + '404': + description: Circle not found + + # Name endpoints + /names: + get: + summary: List all names + description: Returns all name IDs + operationId: listNames + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + type: integer + format: uint32 + post: + summary: Create a new name + description: Creates a new name + operationId: createName + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Name' + responses: + '201': + description: Name created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Name' + + /names/all: + get: + summary: Get all names + description: Returns all names + operationId: getAllNames + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Name' + + /names/{id}: + get: + summary: Get name by ID + description: Returns a single name + operationId: getNameById + parameters: + - name: id + in: path + description: ID of name to return + required: true + schema: + type: integer + format: uint32 + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Name' + '404': + description: Name not found + put: + summary: Update a name + description: Updates an existing name + operationId: updateName + parameters: + - name: id + in: path + description: ID of name to update + required: true + schema: + type: integer + format: uint32 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Name' + responses: + '200': + description: Name updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Name' + '404': + description: Name not found + delete: + summary: Delete a name + description: Deletes a name + operationId: deleteName + parameters: + - name: id + in: path + description: ID of name to delete + required: true + schema: + type: integer + format: uint32 + responses: + '204': + description: Name deleted successfully + '404': + description: Name not found + + /names/domain/{domain}: + get: + summary: Get name by domain + description: Returns a single name by its domain + operationId: getNameByDomain + parameters: + - name: domain + in: path + description: Domain of name to return + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Name' + '404': + description: Name not found + delete: + summary: Delete a name by domain + description: Deletes a name by its domain + operationId: deleteNameByDomain + parameters: + - name: domain + in: path + description: Domain of name to delete + required: true + schema: + type: string + responses: + '204': + description: Name deleted successfully + '404': + description: Name not found