forked from projectcalico/felix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deployment.go
129 lines (118 loc) · 3.25 KB
/
deployment.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
// Copyright (c) 2017 Tigera, Inc. All rights reserved.
//
// 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 main
import (
"fmt"
"math/rand"
"sync"
log "github.com/sirupsen/logrus"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
type host struct {
name string
isLocal bool
}
type deployment interface {
ChooseHost(clientset *kubernetes.Clientset) host
}
type localPlusRemotes struct {
numLocal int
numRemotes int
remotePrefix string
localHostname string
k8sCreated map[string]bool
mutex sync.Mutex
}
func NewDeployment(
clientset *kubernetes.Clientset,
numRemotes int,
includeLocal bool,
) deployment {
numLocal := 0
if includeLocal {
numLocal = 1
}
d := &localPlusRemotes{
numLocal: numLocal,
numRemotes: numRemotes,
remotePrefix: "remote-host-",
k8sCreated: map[string]bool{},
}
if includeLocal {
d.localHostname = felixHostname
}
// Regardless of whether we're going to place _pods_ on the local host, we need to define a
// Node resource for the local host, so that Felix can get going.
d.ensureNodeDefined(clientset, felixHostname, felixIP+"/24")
localFelixConfigured = true
return d
}
var GetNextRemoteHostCIDR = ipAddrAllocator("11.65.%d.%d/16")
func (d *localPlusRemotes) ensureNodeDefined(
clientset *kubernetes.Clientset,
hostName string,
hostCIDR string,
) {
d.mutex.Lock()
if !d.k8sCreated[hostName] {
if hostCIDR == "" {
hostCIDR = GetNextRemoteHostCIDR()
}
node_in := &v1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: hostName,
Annotations: map[string]string{
"projectcalico.org/IPv4Address": hostCIDR,
},
},
Spec: v1.NodeSpec{},
}
log.WithField("node_in", node_in).Debug("Node defined")
node_out, err := clientset.CoreV1().Nodes().Create(node_in)
log.WithField("node_out", node_out).Debug("Created node")
if err != nil {
panic(err)
}
d.k8sCreated[hostName] = true
}
d.mutex.Unlock()
}
func (d *localPlusRemotes) ChooseHost(clientset *kubernetes.Clientset) (h host) {
r := rand.Intn(d.numLocal + d.numRemotes)
if r < d.numLocal {
h = host{name: d.localHostname, isLocal: true}
} else {
h = host{name: fmt.Sprintf("%s%d", d.remotePrefix, r), isLocal: false}
}
d.ensureNodeDefined(clientset, h.name, "")
return
}
func cleanupAllNodes(clientset *kubernetes.Clientset) {
log.Info("Cleaning up all nodes...")
nodeList, err := clientset.CoreV1().Nodes().List(metav1.ListOptions{})
if err != nil {
panic(err)
}
log.WithField("count", len(nodeList.Items)).Info("Nodes present")
for _, node := range nodeList.Items {
err = clientset.CoreV1().Nodes().Delete(node.ObjectMeta.Name, deleteImmediately)
if err != nil {
panic(err)
}
}
log.Info("Cleaned up all nodes")
localFelixConfigured = false
}