* Vendors packages * Adds a Makefile that uses docker to build a static binary against musl using alpine linux. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
157 lines
4.8 KiB
Go
157 lines
4.8 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// OperationClassTask represents the Task OperationClass
|
|
const OperationClassTask = "task"
|
|
|
|
// OperationClassWebsocket represents the Websocket OperationClass
|
|
const OperationClassWebsocket = "websocket"
|
|
|
|
// OperationClassToken represents the Token OperationClass
|
|
const OperationClassToken = "token"
|
|
|
|
// Operation represents a LXD background operation
|
|
//
|
|
// swagger:model
|
|
type Operation struct {
|
|
// UUID of the operation
|
|
// Example: 6916c8a6-9b7d-4abd-90b3-aedfec7ec7da
|
|
ID string `json:"id" yaml:"id"`
|
|
|
|
// Type of operation (task, token or websocket)
|
|
// Example: websocket
|
|
Class string `json:"class" yaml:"class"`
|
|
|
|
// Description of the operation
|
|
// Example: Executing command
|
|
Description string `json:"description" yaml:"description"`
|
|
|
|
// Operation creation time
|
|
// Example: 2021-03-23T17:38:37.753398689-04:00
|
|
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
|
|
|
|
// Operation last change
|
|
// Example: 2021-03-23T17:38:37.753398689-04:00
|
|
UpdatedAt time.Time `json:"updated_at" yaml:"updated_at"`
|
|
|
|
// Status name
|
|
// Example: Running
|
|
Status string `json:"status" yaml:"status"`
|
|
|
|
// Status code
|
|
// Example: 103
|
|
StatusCode StatusCode `json:"status_code" yaml:"status_code"`
|
|
|
|
// Affected resourcs
|
|
// Example: {"containers": ["/1.0/containers/foo"], "instances": ["/1.0/instances/foo"]}
|
|
Resources map[string][]string `json:"resources" yaml:"resources"`
|
|
|
|
// Operation specific metadata
|
|
// Example: {"command": ["bash"], "environment": {"HOME": "/root", "LANG": "C.UTF-8", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "TERM": "xterm", "USER": "root"}, "fds": {"0": "da3046cf02c0116febf4ef3fe4eaecdf308e720c05e5a9c730ce1a6f15417f66", "1": "05896879d8692607bd6e4a09475667da3b5f6714418ab0ee0e5720b4c57f754b"}, "interactive": true}
|
|
Metadata map[string]any `json:"metadata" yaml:"metadata"`
|
|
|
|
// Whether the operation can be canceled
|
|
// Example: false
|
|
MayCancel bool `json:"may_cancel" yaml:"may_cancel"`
|
|
|
|
// Operation error mesage
|
|
// Example: Some error message
|
|
Err string `json:"err" yaml:"err"`
|
|
|
|
// What cluster member this record was found on
|
|
// Example: lxd01
|
|
//
|
|
// API extension: operation_location
|
|
Location string `json:"location" yaml:"location"`
|
|
}
|
|
|
|
// ToCertificateAddToken creates a certificate add token from the operation metadata.
|
|
func (op *Operation) ToCertificateAddToken() (*CertificateAddToken, error) {
|
|
req, ok := op.Metadata["request"].(map[string]any)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation request is type %T not map[string]any", op.Metadata["request"])
|
|
}
|
|
|
|
clientName, ok := req["name"].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Failed to get client name")
|
|
}
|
|
|
|
secret, ok := op.Metadata["secret"].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation secret is type %T not string", op.Metadata["secret"])
|
|
}
|
|
|
|
fingerprint, ok := op.Metadata["fingerprint"].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation fingerprint is type %T not string", op.Metadata["fingerprint"])
|
|
}
|
|
|
|
addresses, ok := op.Metadata["addresses"].([]any)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation addresses is type %T not []any", op.Metadata["addresses"])
|
|
}
|
|
|
|
joinToken := CertificateAddToken{
|
|
ClientName: clientName,
|
|
Secret: secret,
|
|
Fingerprint: fingerprint,
|
|
Addresses: make([]string, 0, len(addresses)),
|
|
}
|
|
|
|
for i, address := range addresses {
|
|
addressString, ok := address.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation address index %d is type %T not string", i, address)
|
|
}
|
|
|
|
joinToken.Addresses = append(joinToken.Addresses, addressString)
|
|
}
|
|
|
|
return &joinToken, nil
|
|
}
|
|
|
|
// ToClusterJoinToken creates a cluster join token from the operation metadata.
|
|
func (op *Operation) ToClusterJoinToken() (*ClusterMemberJoinToken, error) {
|
|
serverName, ok := op.Metadata["serverName"].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation serverName is type %T not string", op.Metadata["serverName"])
|
|
}
|
|
|
|
secret, ok := op.Metadata["secret"].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation secret is type %T not string", op.Metadata["secret"])
|
|
}
|
|
|
|
fingerprint, ok := op.Metadata["fingerprint"].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation fingerprint is type %T not string", op.Metadata["fingerprint"])
|
|
}
|
|
|
|
addresses, ok := op.Metadata["addresses"].([]any)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation addresses is type %T not []any", op.Metadata["addresses"])
|
|
}
|
|
|
|
joinToken := ClusterMemberJoinToken{
|
|
ServerName: serverName,
|
|
Secret: secret,
|
|
Fingerprint: fingerprint,
|
|
Addresses: make([]string, 0, len(addresses)),
|
|
}
|
|
|
|
for i, address := range addresses {
|
|
addressString, ok := address.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Operation address index %d is type %T not string", i, address)
|
|
}
|
|
|
|
joinToken.Addresses = append(joinToken.Addresses, addressString)
|
|
}
|
|
|
|
return &joinToken, nil
|
|
}
|