Uniformisation and verification of admiralty link with nodes + token

This commit is contained in:
pb
2025-02-27 17:00:36 +01:00
parent 44abc073c4
commit 74ac2b6d9c
5 changed files with 176 additions and 32 deletions

View File

@@ -5,8 +5,12 @@ import (
"fmt"
"oc-datacenter/infrastructure"
"slices"
"time"
beego "github.com/beego/beego/v2/server/web"
jwt "github.com/golang-jwt/jwt/v5"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/yaml"
)
type KubeInfo struct {
@@ -20,6 +24,12 @@ type Kubeconfig struct {
Data *string
}
type KubeUser struct {
Name string
User struct {
Token string
}
}
// Operations about the admiralty objects of the datacenter
type AdmiraltyController struct {
beego.Controller
@@ -76,9 +86,9 @@ func (c *AdmiraltyController) GetOneTarget() {
// @Description Create an Admiralty Source on remote cluster
// @Param dc_id path string true "which dc to contact"
// @Param execution path string true "execution id of the workflow"
// @Param serviceAccount body controllers.KubeInfo true "url and serviceAccount to use with the source formatted as json object"
// @Param kubeconfigInfo body controllers.KubeInfo true "url and serviceAccount to use with the source formatted as json object"
// @Success 200
// @router /sources/:dc_id/:execution [post]
// @router /source/:dc_id/:execution [post]
func (c *AdmiraltyController) CreateSource() {
var data KubeInfo
json.Unmarshal(c.Ctx.Input.CopyBody(10000000),&data)
@@ -114,7 +124,7 @@ func (c *AdmiraltyController) CreateSource() {
return
}
res, err := serv.CreateAdmiraltySource(execution)
res, err := serv.CreateAdmiraltySource(c.Ctx.Request.Context(),execution)
if err != nil {
// change code to 500
c.Ctx.Output.SetStatus(500)
@@ -152,7 +162,7 @@ func (c *AdmiraltyController) CreateAdmiraltyTarget(){
return
}
resp, err := serv.CreateAdmiraltyTarget(execution)
resp, err := serv.CreateAdmiraltyTarget(c.Ctx.Request.Context(),execution)
if err != nil {
// change code to 500
c.Ctx.Output.SetStatus(500)
@@ -204,7 +214,7 @@ func(c *AdmiraltyController) GetKubeSecret() {
return
}
resp, err := serv.GetKubeconfigSecret(execution)
resp, err := serv.GetKubeconfigSecret(c.Ctx.Request.Context(),execution)
if err != nil {
// change code to 500
c.Ctx.Output.SetStatus(500)
@@ -268,7 +278,7 @@ func (c *AdmiraltyController) CreateKubeSecret() {
return
}
resp, err := serv.CreateKubeconfigSecret(*kubeconfig.Data,execution)
resp, err := serv.CreateKubeconfigSecret(c.Ctx.Request.Context(),*kubeconfig.Data,execution)
if err != nil {
// change code to 500
c.Ctx.Output.SetStatus(500)
@@ -281,4 +291,101 @@ func (c *AdmiraltyController) CreateKubeSecret() {
c.Data["json"] = respData
c.ServeJSON()
}
// @name GetAdmiraltyNodes
// @description Allows user to test if an admiralty connection has already been established : Target and valid Secret set up on the local host and Source set up on remote host
// @Param dc_id path string true "which dc to contact"
// @Param execution path string true "execution id of the workflow"
// @Success 200
// @Success 203
// @router /node/:dc_id/:execution [get]
func (c *AdmiraltyController) GetNodeReady(){
var secret v1.Secret
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
}
node, err := serv.GetOneNode(c.Ctx.Request.Context(),execution)
if err != nil {
// change code to 500
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
if node == nil {
c.Ctx.Output.SetStatus(404)
c.Data["json"] = map[string]string{
"error" : "the node for " + execution + " can't be found, make sure both target and source resources are set up on local and remote hosts",
}
c.ServeJSON()
return
}
resp, err := serv.GetKubeconfigSecret(c.Ctx.Request.Context(),execution)
if err != nil {
// change code to 500
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
if resp == nil {
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]string{"error": "Nodes was up but the secret can't be found"}
c.ServeJSON()
return
}
// Extract JWT token RS265 encoded
var editedKubeconfig map[string]interface{}
var kubeUsers []KubeUser
json.Unmarshal(resp,&secret)
byteEditedKubeconfig := secret.Data["config"]
err = yaml.Unmarshal(byteEditedKubeconfig,&editedKubeconfig)
// err = json.Unmarshal(byteEditedKubeconfig,&editedKubeconfig)
if err != nil {
fmt.Println("Error while retrieving the kubeconfig from secret-",execution)
fmt.Println(err)
c.Ctx.Output.SetStatus(500)
c.Data["json"] = err
c.ServeJSON()
return
}
b, err := json.Marshal(editedKubeconfig["users"])
err = yaml.Unmarshal(b,&kubeUsers)
token := kubeUsers[0].User.Token
// Decode token
t, _, err := new(jwt.Parser).ParseUnverified(token, jwt.MapClaims{})
if err != nil {
fmt.Println("couldn't decode token")
c.Data["json"] = false
c.ServeJSON()
}
expiration, err := t.Claims.GetExpirationTime()
fmt.Println("Expiration date : " + expiration.UTC().Format("2006-01-02T15:04:05"))
if expiration.Add(1 * time.Hour).Unix() < time.Now().Unix() {
c.Data["json"] = map[string]string{
"token" : "token in the secret is expired and must be regenerated",
}
c.ServeJSON()
}
c.Data["json"] = map[string]bool{"ok": true}
c.ServeJSON()
}

View File

@@ -21,6 +21,8 @@ type BookingController struct {
beego.Controller
}
var BookingExample booking.Booking
// @Title Search
// @Description search bookings by execution
// @Param id path string true "id execution"
@@ -209,7 +211,13 @@ func (o *BookingController) Post() {
*/
var resp booking.Booking
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
json.Unmarshal(o.Ctx.Input.CopyBody(10000000), &resp)
err := json.Unmarshal(o.Ctx.Input.CopyBody(10000000), &resp)
if err != nil {
fmt.Println("Error unmarshalling")
fmt.Println(err)
fmt.Println(resp)
}
dc_id := resp.ResourceID
// delete all previous bookings
isDraft := o.Ctx.Input.Query("is_draft")

View File

@@ -40,7 +40,7 @@ func (o *SessionController) GetToken() {
return
}
fmt.Println("BLAPO", id, duration)
token, err := serv.GetToken(o.Ctx.Request.Context(), id, duration)
token, err := serv.GenerateToken(o.Ctx.Request.Context(), id, duration)
if err != nil {
// change code to 500
o.Ctx.Output.SetStatus(500)