2025-06-26 10:31:48 +02:00
package controllers
2025-06-30 12:33:24 +02:00
import (
2025-08-01 13:02:12 +02:00
"encoding/json"
2025-06-30 12:33:24 +02:00
"oc-datacenter/infrastructure"
oclib "cloud.o-forge.io/core/oc-lib"
"cloud.o-forge.io/core/oc-lib/models/live"
beego "github.com/beego/beego/v2/server/web"
)
2025-06-26 10:31:48 +02:00
type MinioController struct {
beego . Controller
}
// @Title CreateServiceAccounnt
2025-08-01 13:02:12 +02:00
// @Description Add a new ServiceAccount to a Minio server using its ID and an execution ID and store the secret holding the login in the appropriate namespace
2025-08-01 17:42:22 +02:00
// @Success 201
2025-08-01 16:23:41 +02:00
// @Param executions path string true "The executionsID of the execution"
// @Param minioId path string true "The ID of the Minio you want to reach"
// @Param retrieve body map[string]string false "Should be empty or contain "'retrieve': true"
2025-06-30 17:08:01 +02:00
// @router /serviceaccount/:minioId/:executions [post]
2025-06-26 10:31:48 +02:00
func ( m * MinioController ) CreateServiceAccount ( ) {
2025-06-30 12:33:24 +02:00
_ , peerID , _ := oclib . ExtractTokenInfo ( * m . Ctx . Request )
// This part is solely for dev purposes and should be removed once test on
2025-08-01 13:02:12 +02:00
2025-06-26 10:31:48 +02:00
executionsId := m . Ctx . Input . Param ( ":executions" )
minioId := m . Ctx . Input . Param ( ":minioId" )
2025-06-30 12:33:24 +02:00
2025-08-01 13:02:12 +02:00
var b map [ string ] interface { }
2025-08-01 16:28:49 +02:00
retrieve := false
2025-08-01 13:02:12 +02:00
json . Unmarshal ( m . Ctx . Input . CopyBody ( 10000 ) , & b )
if r , ok := b [ "retrieve" ] ; ok {
retrieve = r . ( bool )
2025-06-30 12:33:24 +02:00
}
2025-08-01 13:02:12 +02:00
// retrieve the live storage with the minioId
access , secret , ok := m . createServiceAccount ( minioId , peerID , executionsId )
if ! ok {
2025-06-30 12:33:24 +02:00
return
}
2025-08-01 13:02:12 +02:00
if retrieve {
m . Ctx . Output . SetStatus ( 201 )
m . Data [ "json" ] = map [ string ] string { "access" : access , "secret" : secret }
2025-07-28 12:20:01 +02:00
m . ServeJSON ( )
return
}
2025-06-30 12:33:24 +02:00
// test if the namespace exists
k , err := infrastructure . NewService ( )
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
m . Data [ "json" ] = map [ string ] string { "error" : err . Error ( ) }
m . ServeJSON ( )
return
}
ns , err := k . GetNamespace ( m . Ctx . Request . Context ( ) , executionsId )
if ns == nil {
m . Ctx . Output . SetStatus ( 403 )
m . Data [ "json" ] = map [ string ] string { "error" : "Could not find the namespace corresponding to executionsID " + executionsId }
m . ServeJSON ( )
return
}
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
m . Data [ "json" ] = map [ string ] string { "error" : "Error when trying to check if namespace " + executionsId + " exists : " + err . Error ( ) }
m . ServeJSON ( )
return
}
// store the credentials in the namespace
err = k . CreateSecret ( m . Ctx . Request . Context ( ) , minioId , executionsId , access , secret )
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
m . Data [ "json" ] = map [ string ] string { "error" : "Error when storing Minio serviceAccount credentials in namespace " + executionsId + " exists : " + err . Error ( ) }
m . ServeJSON ( )
return
}
2025-06-30 12:36:21 +02:00
m . Data [ "json" ] = map [ string ] string { "success" : "created secret " + executionsId + "-secret-sa in namespace ns-" + executionsId }
2025-06-26 10:31:48 +02:00
m . ServeJSON ( )
2025-06-30 12:33:24 +02:00
}
2025-08-01 13:02:12 +02:00
func ( m * MinioController ) createServiceAccount ( minioId string , peerID string , executionsId string ) ( string , string , bool ) {
s := oclib . NewRequest ( oclib . LibDataEnum ( oclib . STORAGE_RESOURCE ) , "" , "" , [ ] string { } , nil ) . LoadOne ( minioId )
if s . Err != "" {
m . Ctx . Output . SetStatus ( 400 )
m . Data [ "json" ] = map [ string ] interface { } { "error" : " Could not load the storage resource with id " + minioId + ": " + s . Err }
m . ServeJSON ( )
return "" , "" , false
}
live := findLiveStorage ( minioId , peerID )
if live == nil {
m . Ctx . Output . SetStatus ( 404 )
m . Data [ "json" ] = map [ string ] interface { } { "error" : "could not find the Minio instance " + s . Err }
m . ServeJSON ( )
return "" , "" , false
}
url := live . Source
service := infrastructure . NewMinioService ( url )
// call the method ctrating the svcacc
err := service . CreateClient ( )
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
m . Data [ "json" ] = map [ string ] interface { } { "error" : "could not create the client for " + minioId + " : " + err . Error ( ) }
m . ServeJSON ( )
return "" , "" , false
}
access , secret , err := service . CreateCredentials ( executionsId )
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
m . Data [ "json" ] = map [ string ] interface { } { "error" : "could not create the service account for " + minioId + " : " + err . Error ( ) }
m . ServeJSON ( )
return "" , "" , false
}
err = service . CreateBucket ( executionsId )
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
2025-08-01 16:23:41 +02:00
m . Data [ "json" ] = map [ string ] interface { } { "error" : "error while creating the service account for " + minioId + " : " + err . Error ( ) }
2025-08-01 13:02:12 +02:00
m . ServeJSON ( )
return "" , "" , false
}
return access , secret , true
}
2025-06-30 12:33:24 +02:00
func findLiveStorage ( storageId string , peerId string ) * live . LiveStorage {
res := oclib . NewRequest ( oclib . LibDataEnum ( oclib . LIVE_STORAGE ) , "" , peerId , [ ] string { } , nil ) . LoadAll ( false )
if res . Err != "" {
l := oclib . GetLogger ( )
l . Error ( ) . Msg ( res . Err )
return nil
}
for _ , dbo := range res . Data {
r := oclib . NewRequest ( oclib . LibDataEnum ( oclib . LIVE_STORAGE ) , "" , "" , [ ] string { } , nil ) . LoadOne ( dbo . GetID ( ) )
l := r . ToLiveStorage ( )
for _ , id := range l . ResourcesID {
if id == storageId {
return l
}
}
}
return nil
2025-08-01 17:42:22 +02:00
}
// @Title CreateCredentialsSecret
// @Description Create a Kubernetes secret holding the access and secret keys to a given S3 server and bucket
// @Success 201
// @Param executions path string true "The executionsID of the execution"
// @Param minioId path string true "The ID of the Minio youto which the credentials give access to"
// @Param creds body map[string]string true "The credentials to store in the secret"
// @router /secret/:minioId/:executions [post]
func ( m * MinioController ) CreateCredentialHoldingSecret ( ) {
executionsId := m . Ctx . Input . Param ( ":executions" )
minioId := m . Ctx . Input . Param ( ":minioId" )
var creds map [ string ] string
json . Unmarshal ( m . Ctx . Input . CopyBody ( 10000 ) , & creds )
access , aOk := creds [ "access" ]
secret , sOk := creds [ "secret" ]
if ! aOk || ! sOk || len ( access ) == 0 || len ( secret ) == 0 {
m . Ctx . Output . SetStatus ( 403 )
m . Data [ "json" ] = map [ string ] interface { } { "error" : "Missing credentials" }
m . ServeJSON ( )
}
// test if the namespace exists
k , err := infrastructure . NewService ( )
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
m . Data [ "json" ] = map [ string ] string { "error" : err . Error ( ) }
m . ServeJSON ( )
return
}
ns , err := k . GetNamespace ( m . Ctx . Request . Context ( ) , executionsId )
if ns == nil {
m . Ctx . Output . SetStatus ( 403 )
m . Data [ "json" ] = map [ string ] string { "error" : "Could not find the namespace corresponding to executionsID " + executionsId }
m . ServeJSON ( )
return
}
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
m . Data [ "json" ] = map [ string ] string { "error" : "Error when trying to check if namespace " + executionsId + " exists : " + err . Error ( ) }
m . ServeJSON ( )
return
}
// store the credentials in the namespace
err = k . CreateSecret ( m . Ctx . Request . Context ( ) , minioId , executionsId , creds [ "access" ] , creds [ "secret" ] )
if err != nil {
m . Ctx . Output . SetStatus ( 500 )
m . Data [ "json" ] = map [ string ] string { "error" : "Error when storing Minio serviceAccount credentials in namespace " + executionsId + " exists : " + err . Error ( ) }
m . ServeJSON ( )
return
}
m . Ctx . Output . SetStatus ( 201 )
}