Added new route to retrieve the host's kubeconfig with the execution's SA token

This commit is contained in:
pb
2025-02-28 14:07:45 +01:00
parent 7b27945493
commit f75499d827
4 changed files with 183 additions and 5 deletions

View File

@@ -1,9 +1,12 @@
package controllers
import (
"encoding/base64"
"encoding/json"
"fmt"
"oc-datacenter/conf"
"oc-datacenter/infrastructure"
"oc-datacenter/models"
"slices"
"time"
@@ -20,7 +23,7 @@ type KubeInfo struct {
KubeKey *string
}
type Kubeconfig struct {
type RemoteKubeconfig struct {
Data *string
}
@@ -30,6 +33,35 @@ type KubeUser struct {
Token string
}
}
type KubeconfigToken struct {
ApiVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Preferences string `yaml:"preferences"`
CurrentContext string `yaml:"current-context"`
Clusters []struct{
Cluster struct{
CA string `yaml:"certificate-authority-data"`
Server string `yaml:"server"`
} `yaml:"cluster"`
Name string `yaml:"name"`
} `yaml:"clusters"`
Contexts []struct{
Context struct{
Cluster string `yaml:"cluster"`
User string `yaml:"user"`
} `yaml:"context"`
Name string `yaml:"name"`
} `yaml:"contexts"`
Users []struct{
Name string `yaml:"name"`
User struct {
Token string `yaml:"token"`
} `yaml:"user"`
} `yaml:"users"`
}
// Operations about the admiralty objects of the datacenter
type AdmiraltyController struct {
beego.Controller
@@ -250,7 +282,7 @@ func(c *AdmiraltyController) GetKubeSecret() {
// @Success 200
// @router /secret/:dc_id/:execution [post]
func (c *AdmiraltyController) CreateKubeSecret() {
var kubeconfig Kubeconfig
var kubeconfig RemoteKubeconfig
var respData map[string]interface{}
data := c.Ctx.Input.CopyBody(100000)
@@ -388,4 +420,93 @@ func (c *AdmiraltyController) GetNodeReady(){
c.Data["json"] = map[string]bool{"ok": true}
c.ServeJSON()
}
// @name Get Admiralty Kubeconfig
// @description Retrieve a kubeconfig from the host with the token to authenticate as the SA from the namespace identified with execution id
// @Param dc_id path string true "which dc to contact"
// @Param execution path string true "execution id of the workflow"
// @Success 200
// @router /kubeconfig/:dc_id/:execution [get]
func (c *AdmiraltyController) GetAdmiraltyKubeconfig() {
dc_id := c.Ctx.Input.Param(":dc_id")
execution := c.Ctx.Input.Param(":execution")
_ = dc_id
serv, err := infrastructure.NewService()
if err != nil {
// change code to 500
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
generatedToken, err := serv.GenerateToken(c.Ctx.Request.Context(),execution,3600)
if err != nil {
fmt.Println("Couldn't generate a token for ns-", execution)
fmt.Println(err)
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
kubeconfig, err := NewHostKubeWithToken(generatedToken)
if err != nil {
fmt.Println("Could not retrieve the Kubeconfig edited with token")
fmt.Println(err)
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
c.Data["json"] = kubeconfig
c.ServeJSON()
return
}
func NewHostKubeWithToken(token string) (*models.KubeConfigValue, error){
if len(token) == 0 {
return nil, fmt.Errorf("You didn't provide a token to be inserted in the Kubeconfig")
}
encodedCA := base64.StdEncoding.EncodeToString([]byte(conf.GetConfig().KubeCA))
hostKube := models.KubeConfigValue{
APIVersion: "v1",
CurrentContext: "default",
Kind: "Config",
Preferences: struct{}{},
Clusters: []models.KubeconfigNamedCluster{
{
Name: "default",
Cluster: models.KubeconfigCluster{
Server: conf.GetConfig().KubeHost,
CertificateAuthorityData: encodedCA,
},
},
},
Contexts: []models.KubeconfigNamedContext{
{
Name: "default",
Context: models.KubeconfigContext{
Cluster: "default",
User: "default",
},
},
},
Users: []models.KubeconfigUser{
models.KubeconfigUser{
Name: "default",
User: models.KubeconfigUserKeyPair{
Token: token,
},
},
},
}
return &hostKube, nil
}