mirror of
https://github.com/kairos-io/provider-rke2.git
synced 2025-04-27 19:07:05 +00:00
190 lines
4.5 KiB
Go
190 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/kairos-io/kairos/sdk/clusterplugin"
|
|
yip "github.com/mudler/yip/pkg/schema"
|
|
"github.com/sirupsen/logrus"
|
|
"gopkg.in/yaml.v2"
|
|
kyaml "sigs.k8s.io/yaml"
|
|
)
|
|
|
|
const (
|
|
configurationPath = "/etc/rancher/rke2/config.d"
|
|
containerdEnvConfigPath = "/etc/default"
|
|
|
|
serverSystemName = "rke2-server"
|
|
agentSystemName = "rke2-agent"
|
|
K8S_NO_PROXY = ".svc,.svc.cluster,.svc.cluster.local"
|
|
)
|
|
|
|
type RKE2Config struct {
|
|
Token string `yaml:"token"`
|
|
Server string `yaml:"server"`
|
|
TLSSan []string `yaml:"tls-san"`
|
|
}
|
|
|
|
func clusterProvider(cluster clusterplugin.Cluster) yip.YipConfig {
|
|
rke2Config := RKE2Config{
|
|
Token: cluster.ClusterToken,
|
|
// RKE2 server listens on 9345 for node registration https://docs.rke2.io/install/quickstart/#3-configure-the-rke2-agent-service
|
|
Server: fmt.Sprintf("https://%s:9345", cluster.ControlPlaneHost),
|
|
TLSSan: []string{
|
|
cluster.ControlPlaneHost,
|
|
},
|
|
}
|
|
|
|
if cluster.Role == clusterplugin.RoleInit {
|
|
rke2Config.Server = ""
|
|
|
|
}
|
|
|
|
systemName := serverSystemName
|
|
if cluster.Role == clusterplugin.RoleWorker {
|
|
systemName = agentSystemName
|
|
}
|
|
|
|
// ensure we always have a valid user config
|
|
if cluster.Options == "" {
|
|
cluster.Options = "{}"
|
|
}
|
|
|
|
var providerConfig bytes.Buffer
|
|
_ = yaml.NewEncoder(&providerConfig).Encode(&rke2Config)
|
|
|
|
userOptions, _ := kyaml.YAMLToJSON([]byte(cluster.Options))
|
|
options, _ := kyaml.YAMLToJSON(providerConfig.Bytes())
|
|
|
|
proxyValues := proxyEnv(userOptions, cluster.Env)
|
|
|
|
files := []yip.File{
|
|
{
|
|
Path: filepath.Join(configurationPath, "90_userdata.yaml"),
|
|
Permissions: 0400,
|
|
Content: string(userOptions),
|
|
},
|
|
{
|
|
Path: filepath.Join(configurationPath, "99_userdata.yaml"),
|
|
Permissions: 0400,
|
|
Content: string(options),
|
|
},
|
|
}
|
|
|
|
if len(proxyValues) > 0 {
|
|
files = append(files, yip.File{
|
|
Path: filepath.Join(containerdEnvConfigPath, systemName),
|
|
Permissions: 0400,
|
|
Content: proxyValues,
|
|
})
|
|
}
|
|
|
|
cfg := yip.YipConfig{
|
|
Name: "RKE2 Kairos Cluster Provider",
|
|
Stages: map[string][]yip.Stage{
|
|
"boot.before": {
|
|
{
|
|
Name: " Install RKE2 Configuration Files",
|
|
Files: files,
|
|
|
|
Commands: []string{
|
|
fmt.Sprintf("jq -s 'def flatten: reduce .[] as $i([]; if $i | type == \"array\" then . + ($i | flatten) else . + [$i] end); [.[] | to_entries] | flatten | reduce .[] as $dot ({}; .[$dot.key] += $dot.value)' %s/*.yaml > /etc/rancher/rke2/config.yaml", configurationPath),
|
|
},
|
|
},
|
|
{
|
|
Name: "Enable Systemd Services",
|
|
Systemctl: yip.Systemctl{
|
|
Enable: []string{
|
|
systemName,
|
|
},
|
|
Start: []string{
|
|
systemName,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
return cfg
|
|
}
|
|
|
|
func proxyEnv(userOptions []byte, proxyMap map[string]string) string {
|
|
var proxy []string
|
|
|
|
httpProxy := proxyMap["HTTP_PROXY"]
|
|
httpsProxy := proxyMap["HTTP_PROXY"]
|
|
noProxy := getNoProxy(userOptions, proxyMap["NO_PROXY"])
|
|
|
|
if len(httpProxy) > 0 {
|
|
proxy = append(proxy, fmt.Sprintf("HTTP_PROXY=%s", httpProxy))
|
|
proxy = append(proxy, fmt.Sprintf("CONTAINERD_HTTP_PROXY=%s", httpProxy))
|
|
}
|
|
|
|
if len(httpsProxy) > 0 {
|
|
proxy = append(proxy, fmt.Sprintf("HTTPS_PROXY=%s", httpsProxy))
|
|
proxy = append(proxy, fmt.Sprintf("CONTAINERD_HTTPS_PROXY=%s", httpsProxy))
|
|
}
|
|
|
|
if len(noProxy) > 0 {
|
|
proxy = append(proxy, fmt.Sprintf("NO_PROXY=%s", noProxy))
|
|
proxy = append(proxy, fmt.Sprintf("CONTAINERD_NO_PROXY=%s", noProxy))
|
|
}
|
|
|
|
return strings.Join(proxy, "\n")
|
|
}
|
|
|
|
func getNoProxy(userOptions []byte, noProxy string) string {
|
|
|
|
if len(noProxy) > 0 {
|
|
data := make(map[string]interface{})
|
|
err := json.Unmarshal(userOptions, &data)
|
|
if err != nil {
|
|
fmt.Println("error while unmarshalling user options", err)
|
|
}
|
|
|
|
if data != nil {
|
|
clusterCIDR := data["cluster-cidr"].(string)
|
|
serviceCIDR := data["service-cidr"].(string)
|
|
|
|
if len(clusterCIDR) > 0 {
|
|
noProxy = noProxy + "," + clusterCIDR
|
|
}
|
|
if len(serviceCIDR) > 0 {
|
|
noProxy = noProxy + "," + serviceCIDR
|
|
}
|
|
noProxy = noProxy + "," + getNodeCIDR() + "," + K8S_NO_PROXY
|
|
}
|
|
}
|
|
return noProxy
|
|
}
|
|
|
|
func getNodeCIDR() string {
|
|
addrs, _ := net.InterfaceAddrs()
|
|
var result string
|
|
for _, addr := range addrs {
|
|
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
|
if ipnet.IP.To4() != nil {
|
|
result = addr.String()
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func main() {
|
|
plugin := clusterplugin.ClusterPlugin{
|
|
Provider: clusterProvider,
|
|
}
|
|
|
|
if err := plugin.Run(); err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
}
|