-
Notifications
You must be signed in to change notification settings - Fork 48
/
metadata.go
106 lines (88 loc) · 2.73 KB
/
metadata.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package qemu
import (
"context"
"encoding/json"
"errors"
"io"
"net/http"
"net/url"
"github.com/edgelesssys/constellation/v2/internal/cloud/metadata"
)
const qemuMetadataEndpoint = "10.42.0.1:8080"
// Metadata implements core.ProviderMetadata interface for QEMU.
type Metadata struct{}
// Supported is used to determine if metadata API is implemented for this cloud provider.
func (m *Metadata) Supported() bool {
return true
}
// List retrieves all instances belonging to the current constellation.
func (m *Metadata) List(ctx context.Context) ([]metadata.InstanceMetadata, error) {
instancesRaw, err := m.retrieveMetadata(ctx, "/peers")
if err != nil {
return nil, err
}
var instances []metadata.InstanceMetadata
err = json.Unmarshal(instancesRaw, &instances)
return instances, err
}
// Self retrieves the current instance.
func (m *Metadata) Self(ctx context.Context) (metadata.InstanceMetadata, error) {
instanceRaw, err := m.retrieveMetadata(ctx, "/self")
if err != nil {
return metadata.InstanceMetadata{}, err
}
var instance metadata.InstanceMetadata
err = json.Unmarshal(instanceRaw, &instance)
return instance, err
}
// GetInstance retrieves an instance using its providerID.
func (m *Metadata) GetInstance(ctx context.Context, providerID string) (metadata.InstanceMetadata, error) {
instances, err := m.List(ctx)
if err != nil {
return metadata.InstanceMetadata{}, err
}
for _, instance := range instances {
if instance.ProviderID == providerID {
return instance, nil
}
}
return metadata.InstanceMetadata{}, errors.New("instance not found")
}
// GetLoadBalancerEndpoint returns the endpoint of the load balancer.
// For QEMU, the load balancer is the first control plane node returned by the metadata API.
func (m *Metadata) GetLoadBalancerEndpoint(ctx context.Context) (string, error) {
endpointRaw, err := m.retrieveMetadata(ctx, "/endpoint")
if err != nil {
return "", err
}
var endpoint string
err = json.Unmarshal(endpointRaw, &endpoint)
return endpoint, err
}
// UID returns the UID of the constellation.
func (m *Metadata) UID(ctx context.Context) (string, error) {
// We expect only one constellation to be deployed in the same QEMU / libvirt environment.
// the UID can be an empty string.
return "", nil
}
func (m *Metadata) retrieveMetadata(ctx context.Context, uri string) ([]byte, error) {
url := &url.URL{
Scheme: "http",
Host: qemuMetadataEndpoint,
Path: uri,
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url.String(), nil)
if err != nil {
return nil, err
}
res, err := (&http.Client{}).Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
return io.ReadAll(res.Body)
}