Skip to content

Commit

Permalink
Merge pull request #627 from presztak/metadata_configuration
Browse files Browse the repository at this point in the history
Define API and Go client function to access API configuration metadata
  • Loading branch information
stgraber authored Mar 20, 2024
2 parents 41cc5f9 + 8fcc533 commit 201e653
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 0 deletions.
23 changes: 23 additions & 0 deletions client/incus_metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package incus

import (
"fmt"

"github.com/lxc/incus/shared/api"
)

// GetMetadataConfiguration returns a configuration metadata struct.
func (r *ProtocolIncus) GetMetadataConfiguration() (*api.MetadataConfiguration, error) {
metadataConfiguration := api.MetadataConfiguration{}

if !r.HasExtension("metadata_configuration") {
return nil, fmt.Errorf("The server is missing the required \"metadata_configuration\" API extension")
}

_, err := r.queryStruct("GET", "/metadata/configuration", nil, "", &metadataConfiguration)
if err != nil {
return nil, err
}

return &metadataConfiguration, nil
}
3 changes: 3 additions & 0 deletions client/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ type InstanceServer interface {
RenameImageAlias(name string, alias api.ImageAliasesEntryPost) (err error)
DeleteImageAlias(name string) (err error)

// Configuration metadata functions
GetMetadataConfiguration() (meta *api.MetadataConfiguration, err error)

// Network functions ("network" API extension)
GetNetworkNames() (names []string, err error)
GetNetworks() (networks []api.Network, err error)
Expand Down
File renamed without changes.
79 changes: 79 additions & 0 deletions doc/rest-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2432,6 +2432,85 @@ definitions:
title: InstancesPut represents the fields available for a mass update.
type: object
x-go-package: github.com/lxc/incus/shared/api
MetadataConfig:
additionalProperties:
additionalProperties:
$ref: '#/definitions/MetadataConfigGroup'
type: object
description: MetadataConfig repreents metadata about configuration keys
type: object
x-go-package: github.com/lxc/incus/shared/api
MetadataConfigEntityName:
description: |-
MetadataConfigEntityName represents a main API object type
Example: instance
type: string
x-go-package: github.com/lxc/incus/shared/api
MetadataConfigGroup:
description: MetadataConfigGroup represents a group of config keys
properties:
keys:
items:
additionalProperties:
$ref: '#/definitions/MetadataConfigKey'
type: object
type: array
x-go-name: Keys
type: object
x-go-package: github.com/lxc/incus/shared/api
MetadataConfigGroupName:
description: |-
MetadataConfigGroupName represents the name of a group of config keys
Example: volatile
type: string
x-go-package: github.com/lxc/incus/shared/api
MetadataConfigKey:
description: MetadataConfigKey describe a configuration key
properties:
condition:
description: Condition specifies the condition that must be met for the option to be taken into account
example: container
type: string
x-go-name: Condition
defaultdesc:
description: DefaultDesc specify default value for configuration
example: '"`DHCP on eth0`"'
type: string
x-go-name: Default
liveupdate:
description: LiveUpdate specifies whether the server must be restarted for the option to be updated
example: '"no"'
type: string
x-go-name: LiveUpdate
longdesc:
description: LongDesc provides long description for the option
example: '"Specify the kernel modules as a comma-separated list."'
type: string
x-go-name: LongDescription
scope:
description: Scope defines if option apply to cluster or to the local server
example: global
type: string
x-go-name: Scope
shortdesc:
description: ShortDesc provides short description for the configuration
example: '"Kernel modules to load before starting the instance"'
type: string
x-go-name: Description
type:
description: Type specifies the type of the option
example: string
type: string
x-go-name: Type
type: object
x-go-package: github.com/lxc/incus/shared/api
MetadataConfiguration:
description: MetadataConfiguration represents a server's exposed configuration metadata
properties:
configs:
$ref: '#/definitions/MetadataConfig'
type: object
x-go-package: github.com/lxc/incus/shared/api
Network:
description: Network represents a network
properties:
Expand Down
109 changes: 109 additions & 0 deletions shared/api/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package api

import (
"fmt"
)

// MetadataConfiguration represents a server's exposed configuration metadata
//
// swagger:model
//
// API extension: metadata_configuration.
type MetadataConfiguration struct {
// Metadata about configuration keys.
// Example: {'configs': {'instance': {...}}}
Config MetadataConfig `json:"configs" yaml:"configs"`
}

// GetKeys provides an easy way to interact with MetadataConfiguration.
func (m *MetadataConfiguration) GetKeys(entity string, group string) (map[string]MetadataConfigKey, error) {
keys := map[string]MetadataConfigKey{}

// Get the entity.
configEntity, ok := m.Config[MetadataConfigEntityName(entity)]
if !ok {
return nil, fmt.Errorf("Requested configuration entity %q doesn't exist", entity)
}

// Get the group.
configGroup, ok := configEntity[MetadataConfigGroupName(group)]
if !ok {
return nil, fmt.Errorf("Requested configuration group %q doesn't exist", group)
}

// Go over the keys.
for _, k := range configGroup.Keys {
for name, entry := range k {
keys[name] = entry
}
}

return keys, nil
}

// MetadataConfig repreents metadata about configuration keys
//
// swagger:model
//
// API extension: metadata_configuration.
type MetadataConfig map[MetadataConfigEntityName]map[MetadataConfigGroupName]MetadataConfigGroup

// MetadataConfigEntityName represents a main API object type
// Example: instance
//
// swagger:model
//
// API extension: metadata_configuration.
type MetadataConfigEntityName string

// MetadataConfigGroupName represents the name of a group of config keys
// Example: volatile
//
// swagger:model
//
// API extension: metadata_configuration.
type MetadataConfigGroupName string

// MetadataConfigGroup represents a group of config keys
//
// swagger:model
//
// API extension: metadata_configuration.
type MetadataConfigGroup struct {
Keys []map[string]MetadataConfigKey `json:"keys" yaml:"keys"`
}

// MetadataConfigKey describe a configuration key
//
// swagger:model
//
// API extension: metadata_configuration.
type MetadataConfigKey struct {
// Condition specifies the condition that must be met for the option to be taken into account
// Example: container
Condition string `json:"condition,omitempty" yaml:"condition,omitempty"`

// Scope defines if option apply to cluster or to the local server
// Example: global
Scope string `json:"scope,omitempty" yaml:"scope,omitempty"`

// Type specifies the type of the option
// Example: string
Type string `json:"type" yaml:"type"`

// DefaultDesc specify default value for configuration
// Example: "`DHCP on eth0`"
Default string `json:"defaultdesc,omitempty" yaml:"defaultdesc,omitempty"`

// LiveUpdate specifies whether the server must be restarted for the option to be updated
// Example: "no"
LiveUpdate string `json:"liveupdate,omitempty" yaml:"liveupdate,omitempty"`

// ShortDesc provides short description for the configuration
// Example: "Kernel modules to load before starting the instance"
Description string `json:"shortdesc" yaml:"shortdesc"`

// LongDesc provides long description for the option
// Example: "Specify the kernel modules as a comma-separated list."
LongDescription string `json:"longdesc" yaml:"longdesc"`
}

0 comments on commit 201e653

Please sign in to comment.