Create an endpoint at /api/v1/import which accepts template and context. The template should be in the shape:
inputs:
name:
display: Name
type: Number|string|<any api resource, ie. Container or Site>|<any validator.js>
resources:
name:
type: <any api resource>
values:
key1: value
key2: {{inputs.name}}
name2:
type: <another api resource>
values:
...
As a practical example, an adiministrator could bootstrap a cluster using the following template:
inputs:
siteName:
display: "Site Name"
type: string
internalDomain:
display: "Internal Domain"
type: domainname # verify valid domain name
externalDomain:
display: "External Domain"
type: domainename
dhcpRangeStart:
display: "DHCP Start"
type: ipAddress
dhcpRangeEnd:
display: "DHCP End"
type: ipAddress
subnetMask:
display: "Subnet Mask"
type: ipAddress
gateway:
display: "Gateway"
type: ipAddress
dnsForwarders:
display: "DNS Forwarders"
type: string # takes multple IPs so can't use ipAddress
externalIp:
display: "External IP"
type: ipAddress
apiUrl:
display: "API Url"
type: url
apiPassword:
display: "API Password"
type: string
resources:
site:
type: Site
values:
name: {{inputs.name}}
internalDomain: {{inputs.internalDomain}}
dhcpRange: "{{inputs.dhcpRangeStart}},{{inputs.dhcpRangeEnd}}"
subnetMask: {{inputs.subnetMask}}
gateway: {{inputs.gateway}}
dnsForwarders: {{inputs.dnsForwarders}}
externalIP: {{inputs.externalIP}}
external-domain:
type: ExternalDomain
values:
name: {{inputs.externalDomain}}
proxmox:
type: ProxmoxImport # this isn't a DB type, but it is an API function
values:
# this demonstrates getting values from another step
# which would require late-binding support.
siteId: {{site.id}}
apiUrl: {{inputs.apiUrl}}
username: root@pam
password: {{inputs.apiPassword}}
manager-container:
type: Container
values:
# This assumes the manager is the first container, which is fine for
# demonstration. This id value should update the container rather than throwing a
# conflict due to conflicting ID values
id: {{proxmox.importedContainers[0].id}}
services:
- type: http
internalPort: 3000
externalHostname: {{proxmox.importedContainers[0].hostname}}
externalDomainId: {{external-domain.id}}
The API route would take a JSON object of the shape: {"template":"...yaml...","context":{"key":"value"}} and the context object is what will be used to render the inputs for the YAML template.
Additional requirements:
- The
/api/v1/import route should not do any processing with the resources past rendering the template. Queue a background job like with creating containers and return it in the API response for polling.
- Neither the background job nor the /import route should do any processing with the resources directly. The background job should resolve the template into the proper API calls via the OpenAPI specification and call those endpoints to do any processing after rendering the templates.
- The shape of the YAML given above should be illustrative only, not hard requirement. The
{{ sigils are modeled off of handlebarsjs, but that is not a strict requirement. As long as the inputs and resources top-level keys are there, you have freedom on the exact syntax and implementation.
- With the current shape, it may be difficult to infer POST to create a new resource or PUT to update an existing resource. It is a requirement that the template application use create-or-update semantics. The template should specify resources in enough detail that either POST (to create) or PUT (to update) the resource could succeed. If it isn't the job should error. If an existing resource is found to need an update on something that can't be changed (such as a container template) I would want to delete then re-create that resource, but that might not always be possible, so throwing an error in that case is also acceptable. Perhaps a
force: true or similar could be added alongside type and values in the resource spec to force re-creation.
- The API requests the background job makes should run as the user that ran the import. This will give access control "for free"
Create an endpoint at
/api/v1/importwhich accepts template and context. The template should be in the shape:As a practical example, an adiministrator could bootstrap a cluster using the following template:
The API route would take a JSON object of the shape:
{"template":"...yaml...","context":{"key":"value"}}and the context object is what will be used to render theinputsfor the YAML template.Additional requirements:
/api/v1/importroute should not do any processing with the resources past rendering the template. Queue a background job like with creating containers and return it in the API response for polling.{{sigils are modeled off of handlebarsjs, but that is not a strict requirement. As long as theinputsandresourcestop-level keys are there, you have freedom on the exact syntax and implementation.force: trueor similar could be added alongsidetypeandvaluesin the resource spec to force re-creation.