-
Notifications
You must be signed in to change notification settings - Fork 14
/
cloud.go
190 lines (165 loc) · 5.07 KB
/
cloud.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
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
Copyright 2020 Elotl Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloud
import (
"encoding/json"
"sort"
"time"
"github.com/elotl/kip/pkg/api"
"k8s.io/apimachinery/pkg/util/sets"
)
const MilpaAPISGName = "CellSecurityGroup"
const PublicCIDR = "0.0.0.0/0"
const RestAPIPort = 6421
const ProviderAWS = "aws"
const ProviderGCE = "gce"
const ProviderAzure = "azure"
const ControllerTagKey = "KipControllerID"
const NameTagKey = "Name"
const NamespaceTagKey = "KipNamespace"
const NametagTagKey = "KipNametag"
const PodNameTagKey = "KipPodName"
type CloudClient interface {
SetBootSecurityGroupIDs([]string)
GetBootSecurityGroupIDs() []string
StartNode(*api.Node, Image, string) (*StartNodeResult, error)
StartSpotNode(*api.Node, Image, string) (*StartNodeResult, error)
// This should always be called from a goroutine as it can take a while
StopInstance(instanceID string) error
WaitForRunning(node *api.Node) ([]api.NetworkAddress, error)
EnsureMilpaSecurityGroups([]string, []string) error
AttachSecurityGroups(node *api.Node, groups []string) error
AssignInstanceProfile(node *api.Node, instanceProfile string) error
ListInstancesFilterID([]string) ([]CloudInstance, error)
ListInstances() ([]CloudInstance, error)
ResizeVolume(node *api.Node, size int64) (error, bool)
GetRegistryAuth() (string, string, error)
GetImage(spec BootImageSpec) (Image, error)
SetSustainedCPU(*api.Node, bool) error
AddInstanceTags(string, map[string]string) error
ConnectWithPublicIPs() bool
ModifySourceDestinationCheck(string, bool) error
RemoveRoute(string, string) error
AddRoute(string, string) error
GetVPCCIDRs() []string
GetDNSInfo() ([]string, []string, error)
CloudStatusKeeper() StatusKeeper
GetSubnets() ([]SubnetAttributes, error)
GetAvailabilityZones() ([]string, error)
GetAttributes() CloudAttributes
IsAvailable() (bool, error)
}
type CloudAttributes struct {
DiskProductName api.StorageType
FixedSizeVolume bool
Provider string
Region string
Zone string
}
type StartNodeResult struct {
InstanceID string
AvailabilityZone string
}
type SubnetAddressAffinity string
const (
PublicAddress SubnetAddressAffinity = "Public"
PrivateAddress SubnetAddressAffinity = "Private"
AnyAddress SubnetAddressAffinity = "Any"
)
type SubnetAttributes struct {
Name string
ID string
CIDR string
AZ string
// In AWS subnets we use the subnets private/public address by default
// flag to decide where to launch public and private nodes. We store
// that info in AddressAffinity. In Azure, it's likely we don't have
// that type of affinity (there's some interesting NAT options in azure)
// so we don't really care what subnet our public and private addresses
// go in. Also, this is half baked so if you have an idea of a better
// way to specify placement, knock yourself out.
AddressAffinity SubnetAddressAffinity
// In AWS and Azure (pretty sure...), we can get availability
// stats However, they're harder to come by in GCE. That said, in
// GCE you can resize your subnets and we can always query
// instances and bucket them.
AvailableAddresses int
//Capacity int
}
type Image struct {
ID string
Name string
RootDevice string
CreationTime *time.Time
}
func SortImagesByCreationTime(images []Image) {
sort.Slice(images, func(i, j int) bool {
creationI := images[i].CreationTime
creationJ := images[j].CreationTime
if creationI == nil {
return true
}
if creationJ == nil {
return false
}
return creationI.Before(*creationJ)
})
}
type BootImageSpec map[string]string
func (bis *BootImageSpec) String() string {
data, err := json.Marshal(bis)
if err != nil {
return ""
}
return string(data)
}
type CloudInstance struct {
ID string
NodeName string
}
type ContainerInstance struct {
ID string
}
// List instances only gives us security identifier
type SecurityGroupIdentifier struct {
ID string
Name string
}
type SecurityGroup struct {
ID string
Name string
Ports []InstancePort
SourceRanges []string
}
func NewSecurityGroup(id, name string, ports []InstancePort, sources []string) SecurityGroup {
sort.Sort(SortableSliceOfPorts(ports))
sort.Strings(sources)
return SecurityGroup{
ID: id,
Name: name,
Ports: ports,
SourceRanges: sources,
}
}
type LoadBalancer struct {
Type string
ServiceName string
LoadBalancerName string
Instances sets.String
Ports []InstancePort
SecurityGroupID string
Internal bool
Annotations map[string]string
DNSName string
IPAddress string
}