package main import ( "bytes" "fmt" "github.com/c3os-io/c3os/provider-k3s/api" "github.com/c3os-io/c3os/sdk/clusterplugin" yip "github.com/mudler/yip/pkg/schema" "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" "path/filepath" kyaml "sigs.k8s.io/yaml" ) const ( configurationPath = "/etc/rancher/k3s/config.d" serverSystemName = "k3s" agentSystemName = "k3s-agent" ) func clusterProvider(cluster clusterplugin.Cluster) yip.YipConfig { k3sConfig := api.K3sServerConfig{ Token: cluster.ClusterToken, } var userOptionConfig string switch cluster.Role { case clusterplugin.RoleInit: k3sConfig.ClusterInit = true k3sConfig.TLSSan = []string{cluster.ControlPlaneHost} userOptionConfig = cluster.Options case clusterplugin.RoleControlPlane: k3sConfig.Server = fmt.Sprintf("https://%s:6443", cluster.ControlPlaneHost) k3sConfig.TLSSan = []string{cluster.ControlPlaneHost} userOptionConfig = cluster.Options case clusterplugin.RoleWorker: k3sConfig.Server = fmt.Sprintf("https://%s:6443", cluster.ControlPlaneHost) //Data received from upstream contains config for both control plane and worker. Thus, for worker, config is being filtered //via unmarshal into agent config. var agentCfg api.K3sAgentConfig if err := yaml.Unmarshal([]byte(cluster.Options), &agentCfg); err == nil { out, _ := yaml.Marshal(agentCfg) userOptionConfig = string(out) } } systemName := serverSystemName if cluster.Role == clusterplugin.RoleWorker { systemName = agentSystemName } var providerConfig bytes.Buffer _ = yaml.NewEncoder(&providerConfig).Encode(&k3sConfig) userOptions, _ := kyaml.YAMLToJSON([]byte(userOptionConfig)) options, _ := kyaml.YAMLToJSON(providerConfig.Bytes()) cfg := yip.YipConfig{ Name: "K3s C3OS Cluster Provider", Stages: map[string][]yip.Stage{ "boot.before": { { Name: "Install K3s Configuration Files", 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), }, }, 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/k3s/config.yaml", configurationPath), }, }, { Name: "Enable OpenRC Services", If: "[ -x /sbin/openrc-run ]", Commands: []string{ fmt.Sprintf("rc-update add %s default >/dev/null", systemName), fmt.Sprintf("service %s start", systemName), }, }, { Name: "Enable Systemd Services", If: "[ -x /bin/systemctl ]", Systemctl: yip.Systemctl{ Enable: []string{ systemName, }, Start: []string{ systemName, }, }, }, }, }, } return cfg } func main() { plugin := clusterplugin.ClusterPlugin{ Provider: clusterProvider, } if err := plugin.Run(); err != nil { logrus.Fatal(err) } }