Repository navigation
Expand file tree
/
Copy pathservers.go
More file actions
142 lines (126 loc) · 5.48 KB
/
Copy pathservers.go
File metadata and controls
142 lines (126 loc) · 5.48 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package stackit
import (
"context"
"encoding/base64"
"github.com/stackitcloud/stackit-sdk-go/core/utils"
iaas "github.com/stackitcloud/stackit-sdk-go/services/iaas/v2api"
computev1alpha1 "github.com/bartvanbenthem/stackit-compute-operator/api/v1alpha1"
)
// BuildCreatePayload translates a Server's spec into a STACKIT
// CreateServerPayload. resolvedImageID and resolvedNetworkID are the IDs
// already resolved by the controller from spec.imageId/spec.imageRef and
// spec.networkId/spec.networkRef respectively. resolvedBootVolumeID, when
// non-empty, is the ID of an already-existing Volume (resolved from
// spec.bootVolumeRef) to boot from instead of creating a new boot volume
// from resolvedImageID; in that case spec.bootVolume.size/performanceClass
// are ignored, since the volume already exists, and resolvedImageID may be
// empty (STACKIT's imageId is omitted rather than sent as an empty string).
func BuildCreatePayload(name string, spec computev1alpha1.ServerSpec, resolvedImageID, resolvedNetworkID, resolvedBootVolumeID string) iaas.CreateServerPayload {
payload := iaas.CreateServerPayload{
Name: name,
MachineType: spec.MachineType,
Networking: iaas.CreateServerPayloadAllOfNetworking{
CreateServerNetworking: &iaas.CreateServerNetworking{
NetworkId: utils.Ptr(resolvedNetworkID),
},
},
}
if resolvedImageID != "" {
payload.ImageId = utils.Ptr(resolvedImageID)
}
if spec.AvailabilityZone != "" {
payload.AvailabilityZone = utils.Ptr(spec.AvailabilityZone)
}
if spec.KeypairName != "" {
payload.KeypairName = utils.Ptr(spec.KeypairName)
}
if spec.UserData != "" {
// STACKIT requires user data to be base64-encoded cloud-init.
payload.UserData = utils.Ptr(base64.StdEncoding.EncodeToString([]byte(spec.UserData)))
}
if len(spec.SecurityGroups) > 0 {
payload.SecurityGroups = append([]string(nil), spec.SecurityGroups...)
}
if len(spec.ServiceAccountMails) > 0 {
payload.ServiceAccountMails = append([]string(nil), spec.ServiceAccountMails...)
}
if len(spec.Labels) > 0 {
payload.Labels = toInterfaceMap(spec.Labels)
}
switch {
case resolvedBootVolumeID != "":
payload.BootVolume = &iaas.BootVolume{
Source: &iaas.BootVolumeSource{
Id: resolvedBootVolumeID,
Type: "volume",
},
DeleteOnTermination: spec.BootVolume.DeleteOnTermination,
}
case spec.BootVolume.Size > 0 || spec.BootVolume.PerformanceClass != "" || spec.BootVolume.DeleteOnTermination != nil:
bootVolume := &iaas.BootVolume{
Source: &iaas.BootVolumeSource{
Id: resolvedImageID,
Type: "image",
},
DeleteOnTermination: spec.BootVolume.DeleteOnTermination,
}
if spec.BootVolume.Size > 0 {
bootVolume.Size = utils.Ptr(spec.BootVolume.Size)
}
if spec.BootVolume.PerformanceClass != "" {
bootVolume.PerformanceClass = utils.Ptr(spec.BootVolume.PerformanceClass)
}
payload.BootVolume = bootVolume
}
return payload
}
// BuildUpdatePayload translates the fields that differ between the desired
// spec and the observed STACKIT server into an UpdateServerPayload. An
// empty name or nil labels leave the corresponding field unset.
func BuildUpdatePayload(name string, labels map[string]string) iaas.UpdateServerPayload {
payload := iaas.UpdateServerPayload{}
if name != "" {
payload.Name = utils.Ptr(name)
}
if labels != nil {
payload.Labels = toInterfaceMap(labels)
}
return payload
}
func toInterfaceMap(in map[string]string) map[string]interface{} {
out := make(map[string]interface{}, len(in))
for k, v := range in {
out[k] = v
}
return out
}
// CreateServer triggers creation of a new server and returns the initial
// (still-provisioning) server object.
func CreateServer(ctx context.Context, client *iaas.APIClient, projectID, region string, payload iaas.CreateServerPayload) (*iaas.Server, error) {
return client.DefaultAPI.CreateServer(ctx, projectID, region).CreateServerPayload(payload).Execute()
}
// GetServer fetches the current state of a server from STACKIT.
func GetServer(ctx context.Context, client *iaas.APIClient, projectID, region, serverID string) (*iaas.Server, error) {
return client.DefaultAPI.GetServer(ctx, projectID, region, serverID).Execute()
}
// UpdateServer applies name/label/metadata changes to an existing server.
func UpdateServer(ctx context.Context, client *iaas.APIClient, projectID, region, serverID string, payload iaas.UpdateServerPayload) (*iaas.Server, error) {
return client.DefaultAPI.UpdateServer(ctx, projectID, region, serverID).UpdateServerPayload(payload).Execute()
}
// ResizeServer changes a server's machine type.
func ResizeServer(ctx context.Context, client *iaas.APIClient, projectID, region, serverID, machineType string) error {
payload := iaas.ResizeServerPayload{MachineType: machineType}
return client.DefaultAPI.ResizeServer(ctx, projectID, region, serverID).ResizeServerPayload(payload).Execute()
}
// StartServer powers on a stopped server.
func StartServer(ctx context.Context, client *iaas.APIClient, projectID, region, serverID string) error {
return client.DefaultAPI.StartServer(ctx, projectID, region, serverID).Execute()
}
// StopServer powers off a running server.
func StopServer(ctx context.Context, client *iaas.APIClient, projectID, region, serverID string) error {
return client.DefaultAPI.StopServer(ctx, projectID, region, serverID).Execute()
}
// DeleteServer permanently deletes a server.
func DeleteServer(ctx context.Context, client *iaas.APIClient, projectID, region, serverID string) error {
return client.DefaultAPI.DeleteServer(ctx, projectID, region, serverID).Execute()
}