Compare commits
	
		
			24 Commits
		
	
	
		
			bb03307b9e
			...
			feature/mu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					cb2e4f6028 | ||
| 
						 | 
					35facf1b74 | ||
| 
						 | 
					24e0137444 | ||
| 
						 | 
					ba940bfc80 | ||
| 
						 | 
					063d57d9e7 | ||
| 
						 | 
					484c742c31 | ||
| 
						 | 
					cc3b2a6cfc | ||
| 
						 | 
					8e8d0d3e01 | ||
| 
						 | 
					03f81c66f9 | ||
| 
						 | 
					be721059e5 | ||
| e4f0f6f4ca | |||
| cf92b46ce6 | |||
| aa42f5f49c | |||
| 
						 | 
					98c54eb080 | ||
| afe442d17f | |||
| 
						 | 
					46b7713404 | ||
| d5ad32e2e4 | |||
| 
						 | 
					e4ecb8c1db | ||
| cca59faeab | |||
| 2cf8923d95 | |||
| 47ed1b4562 | |||
| 063f47c87b | |||
| 4bfb16cba6 | |||
| b08e6a1e70 | 
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					ARG KUBERNETES_HOST=${KUBERNETES_HOST:-"127.0.0.1"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FROM golang:alpine AS deps
 | 
					FROM golang:alpine AS deps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /app
 | 
					WORKDIR /app
 | 
				
			||||||
@@ -28,7 +30,7 @@ RUN export CGO_ENABLED=0 && \
 | 
				
			|||||||
COPY . .
 | 
					COPY . .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN sed -i '/replace/d' go.mod
 | 
					RUN sed -i '/replace/d' go.mod
 | 
				
			||||||
RUN if [ ! -f swagger/index.html ]; then timeout 15 bee run --gendoc=true --downdoc=true; fi
 | 
					RUN if [ ! -f swagger/index.html ]; then timeout 15 bee run -gendoc=true -downdoc=true; fi
 | 
				
			||||||
RUN bee generate routers
 | 
					RUN bee generate routers
 | 
				
			||||||
RUN bee generate docs
 | 
					RUN bee generate docs
 | 
				
			||||||
RUN bee pack
 | 
					RUN bee pack
 | 
				
			||||||
@@ -39,6 +41,8 @@ RUN sed -i 's/http:\/\/127.0.0.1:8080\/swagger\/swagger.json/swagger.json/g' /ap
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
FROM golang:alpine
 | 
					FROM golang:alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV KUBERNETES_SERVICE_HOST=$KUBERNETES_HOST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /app
 | 
					WORKDIR /app
 | 
				
			||||||
COPY --from=builder /app/extracted/oc-datacenter /usr/bin/ 
 | 
					COPY --from=builder /app/extracted/oc-datacenter /usr/bin/ 
 | 
				
			||||||
COPY --from=builder /app/extracted/swagger /app/swagger
 | 
					COPY --from=builder /app/extracted/swagger /app/swagger
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,10 +10,13 @@ import (
 | 
				
			|||||||
	"slices"
 | 
						"slices"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						oclib "cloud.o-forge.io/core/oc-lib"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beego "github.com/beego/beego/v2/server/web"
 | 
						beego "github.com/beego/beego/v2/server/web"
 | 
				
			||||||
	jwt "github.com/golang-jwt/jwt/v5"
 | 
						jwt "github.com/golang-jwt/jwt/v5"
 | 
				
			||||||
	"gopkg.in/yaml.v2"
 | 
						"gopkg.in/yaml.v2"
 | 
				
			||||||
	v1 "k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
 | 
						apierrors "k8s.io/apimachinery/pkg/api/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type KubeInfo struct {
 | 
					type KubeInfo struct {
 | 
				
			||||||
@@ -117,12 +120,12 @@ func (c *AdmiraltyController) GetOneTarget() {
 | 
				
			|||||||
	c.ServeJSON()
 | 
						c.ServeJSON()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// @Title CreateSource
 | 
					// @Title CreateAdmiraltySource
 | 
				
			||||||
// @Description Create an Admiralty Source on remote cluster
 | 
					// @Description Create an Admiralty Source on remote cluster
 | 
				
			||||||
// @Param execution path 	string 		true	"execution id of the workflow"
 | 
					// @Param execution path 	string 		true	"execution id of the workflow"
 | 
				
			||||||
// @Success 201 
 | 
					// @Success 201 
 | 
				
			||||||
// @router /source/:execution [post]
 | 
					// @router /source/:execution [post]
 | 
				
			||||||
func (c *AdmiraltyController) CreateSource() {
 | 
					func (c *AdmiraltyController) CreateAdmiraltySource() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	execution := c.Ctx.Input.Param(":execution")
 | 
						execution := c.Ctx.Input.Param(":execution")
 | 
				
			||||||
	fmt.Println("execution :: ", execution)
 | 
						fmt.Println("execution :: ", execution)
 | 
				
			||||||
@@ -139,6 +142,12 @@ func (c *AdmiraltyController) CreateSource() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	res, err := serv.CreateAdmiraltySource(c.Ctx.Request.Context(),execution)
 | 
						res, err := serv.CreateAdmiraltySource(c.Ctx.Request.Context(),execution)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if apierrors.IsAlreadyExists(err) {
 | 
				
			||||||
 | 
								c.Ctx.Output.SetStatus(409)
 | 
				
			||||||
 | 
								c.Data["json"] = map[string]string{"info" : "A source already exists for this namespace : " + execution}
 | 
				
			||||||
 | 
								c.ServeJSON()
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// change code to 500
 | 
							// change code to 500
 | 
				
			||||||
		c.Ctx.Output.SetStatus(500)
 | 
							c.Ctx.Output.SetStatus(500)
 | 
				
			||||||
		c.Data["json"] = map[string]string{"error": err.Error()}
 | 
							c.Data["json"] = map[string]string{"error": err.Error()}
 | 
				
			||||||
@@ -159,13 +168,21 @@ func (c *AdmiraltyController) CreateSource() {
 | 
				
			|||||||
// @Title CreateAdmiraltyTarget
 | 
					// @Title CreateAdmiraltyTarget
 | 
				
			||||||
// @Description Create an Admiralty Target in the namespace associated to the executionID
 | 
					// @Description Create an Admiralty Target in the namespace associated to the executionID
 | 
				
			||||||
// @Param execution path 	string 		true	"execution id of the workflow"
 | 
					// @Param execution path 	string 		true	"execution id of the workflow"
 | 
				
			||||||
 | 
					// @Param peer	path	string	true	"peerId of the peer the target points to"
 | 
				
			||||||
// @Success 201
 | 
					// @Success 201
 | 
				
			||||||
// @router /target/:execution [post]
 | 
					// @router /target/:execution/:peer [post]
 | 
				
			||||||
func (c *AdmiraltyController) CreateAdmiraltyTarget(){
 | 
					func (c *AdmiraltyController) CreateAdmiraltyTarget(){
 | 
				
			||||||
	var data map[string]interface{}
 | 
						var data map[string]interface{}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	execution := c.Ctx.Input.Param(":execution")
 | 
						execution := c.Ctx.Input.Param(":execution")
 | 
				
			||||||
 | 
						peerId := c.Ctx.Input.Param(":peer")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if execution == "" || peerId == "" {
 | 
				
			||||||
 | 
							c.Ctx.Output.SetStatus(400)
 | 
				
			||||||
 | 
							c.Data["json"] = map[string]string{"error" : "parameters can be empty " + "execution: " + execution + " peer: " + peerId}
 | 
				
			||||||
 | 
							c.ServeJSON()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serv, err := infrastructure.NewService()
 | 
						serv, err := infrastructure.NewService()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -176,7 +193,7 @@ func (c *AdmiraltyController) CreateAdmiraltyTarget(){
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp, err := serv.CreateAdmiraltyTarget(c.Ctx.Request.Context(),execution)
 | 
						resp, err := serv.CreateAdmiraltyTarget(c.Ctx.Request.Context(),execution, peerId)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		// change code to 500
 | 
							// change code to 500
 | 
				
			||||||
		c.Ctx.Output.SetStatus(500)
 | 
							c.Ctx.Output.SetStatus(500)
 | 
				
			||||||
@@ -210,14 +227,16 @@ func (c *AdmiraltyController) CreateAdmiraltyTarget(){
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// @Title GetKubeSecret
 | 
					// @Title GetKubeSecret
 | 
				
			||||||
// @Description Retrieve the secret created from a Kubeconfig that will be associated to an Admiralty Target
 | 
					// @Description Retrieve the secret created from a Kubeconfig that will be associated to an Admiralty Target
 | 
				
			||||||
 | 
					 | 
				
			||||||
// @Param execution path 	string 		true	"execution id of the workflow"
 | 
					// @Param execution path 	string 		true	"execution id of the workflow"
 | 
				
			||||||
 | 
					// @Param peer		path 	string 		true	"UUID of the peer to which the resource is linked"
 | 
				
			||||||
// @Success 200 
 | 
					// @Success 200 
 | 
				
			||||||
// @router /secret/:execution [get]
 | 
					// @router /secret/:execution/:peer [get]
 | 
				
			||||||
func(c *AdmiraltyController) GetKubeSecret() {
 | 
					func(c *AdmiraltyController) GetKubeSecret() {
 | 
				
			||||||
	var data map[string]interface{} 
 | 
						var data map[string]interface{} 
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	execution := c.Ctx.Input.Param(":execution")
 | 
						execution := c.Ctx.Input.Param(":execution")
 | 
				
			||||||
 | 
						peerId := c.Ctx.Input.Param(":peer")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serv, err := infrastructure.NewService()
 | 
						serv, err := infrastructure.NewService()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -228,7 +247,7 @@ func(c *AdmiraltyController) GetKubeSecret() {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp, err := serv.GetKubeconfigSecret(c.Ctx.Request.Context(),execution)
 | 
						resp, err := serv.GetKubeconfigSecret(c.Ctx.Request.Context(),execution, peerId)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		// change code to 500
 | 
							// change code to 500
 | 
				
			||||||
		c.Ctx.Output.SetStatus(500)
 | 
							c.Ctx.Output.SetStatus(500)
 | 
				
			||||||
@@ -260,9 +279,10 @@ func(c *AdmiraltyController) GetKubeSecret() {
 | 
				
			|||||||
// @Description Creat a secret from a Kubeconfig that will be associated to an Admiralty Target
 | 
					// @Description Creat a secret from a Kubeconfig that will be associated to an Admiralty Target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// @Param execution path 	string 		true	"execution id of the workflow"
 | 
					// @Param execution path 	string 		true	"execution id of the workflow"
 | 
				
			||||||
 | 
					// @Param peer		path 	string 		true	"UUID of the peer to which the resource is linked"
 | 
				
			||||||
// @Param kubeconfig 	body	controllers.RemoteKubeconfig 		true 	"Kubeconfig to use when creating secret"
 | 
					// @Param kubeconfig 	body	controllers.RemoteKubeconfig 		true 	"Kubeconfig to use when creating secret"
 | 
				
			||||||
// @Success 201 
 | 
					// @Success 201 
 | 
				
			||||||
// @router /secret/:execution [post]
 | 
					// @router /secret/:execution/:peer [post]
 | 
				
			||||||
func (c *AdmiraltyController) CreateKubeSecret() {
 | 
					func (c *AdmiraltyController) CreateKubeSecret() {
 | 
				
			||||||
	var kubeconfig 	RemoteKubeconfig
 | 
						var kubeconfig 	RemoteKubeconfig
 | 
				
			||||||
	var respData	map[string]interface{}
 | 
						var respData	map[string]interface{}
 | 
				
			||||||
@@ -279,9 +299,8 @@ func (c *AdmiraltyController) CreateKubeSecret() {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	execution := c.Ctx.Input.Param(":execution")
 | 
						execution := c.Ctx.Input.Param(":execution")
 | 
				
			||||||
 | 
						peerId := c.Ctx.Input.Param(":peer")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serv, err := infrastructure.NewService()
 | 
						serv, err := infrastructure.NewService()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -292,7 +311,7 @@ func (c *AdmiraltyController) CreateKubeSecret() {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp, err := serv.CreateKubeconfigSecret(c.Ctx.Request.Context(),*kubeconfig.Data,execution)
 | 
						resp, err := serv.CreateKubeconfigSecret(c.Ctx.Request.Context(),*kubeconfig.Data,execution, peerId)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		// change code to 500
 | 
							// change code to 500
 | 
				
			||||||
		c.Ctx.Output.SetStatus(500)
 | 
							c.Ctx.Output.SetStatus(500)
 | 
				
			||||||
@@ -311,13 +330,13 @@ func (c *AdmiraltyController) CreateKubeSecret() {
 | 
				
			|||||||
// @name GetAdmiraltyNodes
 | 
					// @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
 | 
					// @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 execution path 	string 		true	"execution id of the workflow"
 | 
					// @Param execution path 	string 		true	"execution id of the workflow"
 | 
				
			||||||
 | 
					// @Param peer		path 	string 		true	"UUID of the peer to which the resource is linked"
 | 
				
			||||||
// @Success 200 
 | 
					// @Success 200 
 | 
				
			||||||
// @router /node/:execution [get]
 | 
					// @router /node/:execution/:peer [get]
 | 
				
			||||||
func (c *AdmiraltyController) GetNodeReady(){
 | 
					func (c *AdmiraltyController) GetNodeReady(){
 | 
				
			||||||
	var secret v1.Secret
 | 
						var secret v1.Secret
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	execution := c.Ctx.Input.Param(":execution")
 | 
						execution := c.Ctx.Input.Param(":execution")
 | 
				
			||||||
 | 
						peerId := c.Ctx.Input.Param(":peer")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serv, err := infrastructure.NewService()
 | 
						serv, err := infrastructure.NewService()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -339,13 +358,15 @@ func (c *AdmiraltyController) GetNodeReady(){
 | 
				
			|||||||
	if node == nil {
 | 
						if node == nil {
 | 
				
			||||||
		c.Ctx.Output.SetStatus(404)
 | 
							c.Ctx.Output.SetStatus(404)
 | 
				
			||||||
		c.Data["json"] = map[string]string{
 | 
							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",
 | 
								"node" : "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()
 | 
							c.ServeJSON()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp, err := serv.GetKubeconfigSecret(c.Ctx.Request.Context(),execution)
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resp, err := serv.GetKubeconfigSecret(c.Ctx.Request.Context(),execution, peerId)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		// change code to 500
 | 
							// change code to 500
 | 
				
			||||||
		c.Ctx.Output.SetStatus(500)
 | 
							c.Ctx.Output.SetStatus(500)
 | 
				
			||||||
@@ -359,7 +380,6 @@ func (c *AdmiraltyController) GetNodeReady(){
 | 
				
			|||||||
		c.ServeJSON()
 | 
							c.ServeJSON()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Extract JWT token RS265 encoded
 | 
						// Extract JWT token RS265 encoded
 | 
				
			||||||
	var editedKubeconfig map[string]interface{}
 | 
						var editedKubeconfig map[string]interface{}
 | 
				
			||||||
@@ -393,14 +413,15 @@ func (c *AdmiraltyController) GetNodeReady(){
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if *isExpired {
 | 
						if *isExpired {
 | 
				
			||||||
		c.Data["json"] = map[string]string{
 | 
							c.Data["json"] = map[string]interface{}{
 | 
				
			||||||
			"token" : "token in the secret is expired and must be regenerated",
 | 
								"token" : "token in the secret is expired and must be regenerated",
 | 
				
			||||||
 | 
								"node": node,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		c.Ctx.Output.SetStatus(410)
 | 
							c.Ctx.Output.SetStatus(410)
 | 
				
			||||||
		c.ServeJSON()
 | 
							c.ServeJSON()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.Data["json"] = map[string]bool{"ok": true}
 | 
						c.Data["json"] = map[string]interface{}{"node": node,"token": true}
 | 
				
			||||||
	c.ServeJSON()
 | 
						c.ServeJSON()
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -426,6 +447,8 @@ func retrieveTokenFromKonfig(editedKubeconfig map[string]interface{}) (string,er
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func isTokenExpired(token string) (*bool, error){
 | 
					func isTokenExpired(token string) (*bool, error){
 | 
				
			||||||
 | 
						logger := oclib.GetLogger()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t, _, err := new(jwt.Parser).ParseUnverified(token, jwt.MapClaims{})
 | 
						t, _, err := new(jwt.Parser).ParseUnverified(token, jwt.MapClaims{})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("couldn't decode token")
 | 
							fmt.Println("couldn't decode token")
 | 
				
			||||||
@@ -437,7 +460,11 @@ func isTokenExpired(token string) (*bool, error){
 | 
				
			|||||||
		fmt.Println("Error while checking token's expiration time")
 | 
							fmt.Println("Error while checking token's expiration time")
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Println("Expiration date : " + expiration.UTC().Format("2006-01-02T15:04:05"))
 | 
					
 | 
				
			||||||
 | 
						logger.Debug().Msg("Expiration date : " + expiration.UTC().Format("2006-01-02T15:04:05"))
 | 
				
			||||||
 | 
						logger.Debug().Msg(fmt.Sprint("Now : ", time.Now().Unix()))
 | 
				
			||||||
 | 
						logger.Debug().Msg(fmt.Sprint("Token : ", expiration.Unix()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	expired := expiration.Unix() < time.Now().Unix()
 | 
						expired := expiration.Unix() < time.Now().Unix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,6 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"oc-datacenter/infrastructure"
 | 
						"oc-datacenter/infrastructure"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	oclib "cloud.o-forge.io/core/oc-lib"
 | 
						oclib "cloud.o-forge.io/core/oc-lib"
 | 
				
			||||||
@@ -247,19 +246,11 @@ func (o *BookingController) Post() {
 | 
				
			|||||||
		o.ServeJSON()
 | 
							o.ServeJSON()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := o.createNamespace(resp.ExecutionsID); err != nil {
 | 
						if err := o.createNamespace(resp.ExecutionsID); err != nil {
 | 
				
			||||||
		if strings.Contains(err.Error(), "already exists") {
 | 
							fmt.Println(err.Error())
 | 
				
			||||||
			err = nil
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			o.Data["json"] = map[string]interface{}{
 | 
					 | 
				
			||||||
				"data":  nil,
 | 
					 | 
				
			||||||
				"code":  500,
 | 
					 | 
				
			||||||
				"error": err.Error(),
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			o.ServeJSON()
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o.Data["json"] = map[string]interface{}{
 | 
						o.Data["json"] = map[string]interface{}{
 | 
				
			||||||
		"data":  []interface{}{b},
 | 
							"data":  []interface{}{b},
 | 
				
			||||||
		"code":  200,
 | 
							"code":  200,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,8 +3,5 @@
 | 
				
			|||||||
    "NATS_URL": "nats://localhost:4222",
 | 
					    "NATS_URL": "nats://localhost:4222",
 | 
				
			||||||
    "MONGO_DATABASE": "DC_myDC",
 | 
					    "MONGO_DATABASE": "DC_myDC",
 | 
				
			||||||
    "KUBERNETES_SERVICE_HOST": "172.16.0.183",
 | 
					    "KUBERNETES_SERVICE_HOST": "172.16.0.183",
 | 
				
			||||||
    "port": "8092",
 | 
					    "port": "8092"
 | 
				
			||||||
    "KUBE_CA": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlRENDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUzTXpnNE5UazJNVFl3SGhjTk1qVXdNakEyTVRZek16TTJXaGNOTXpVd01qQTBNVFl6TXpNMgpXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUzTXpnNE5UazJNVFl3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFSbi9jVmNUb1orekZUdWZSL29qbG5JMnVpZXJYeTkxcWhxYWpHdWVobXYKV1A4NVQ1dXpkcE1rcFhrNnB5bTlFU0RlRjk1WDFkeTJqdjVFR3paZzZ2WWtvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVXJRK0xUR2NMNXBENnBxSEozaVh5CmZiMFRQUDR3Q2dZSUtvWkl6ajBFQXdJRFNRQXdSZ0loQUlObXp3ejhOUVRCNFlURlZJd3BudDhpQjJ5alRlQjYKbkZxRUN6SWw0amUzQWlFQW04dzRma1h0UEhzUG1Yc0hhUXFGSkhkUm9SQ1pSa016akU3REdZY1lMNVE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
 | 
					 | 
				
			||||||
    "KUBE_CERT": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrVENDQVRlZ0F3SUJBZ0lJYVlyeG5xbm54WEl3Q2dZSUtvWkl6ajBFQXdJd0l6RWhNQjhHQTFVRUF3d1kKYXpOekxXTnNhV1Z1ZEMxallVQXhOek00T0RVNU5qRTJNQjRYRFRJMU1ESXdOakUyTXpNek5sb1hEVEkyTURJdwpOakUyTXpNek5sb3dNREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGVEFUQmdOVkJBTVRESE41CmMzUmxiVHBoWkcxcGJqQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJHeDVVb1Ura01obE9xeHgKTjhRV1FOOGF1ekxXRHpjZTBVbnRYWFdHUmFvWHdHdnlYUldkaFlQcVNoU0xJVGttMG5GV2t5cEZlNUdXTXJlVApZd0hReE9talNEQkdNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFmCkJnTlZIU01FR0RBV2dCU0ZlbDVtUXNEaW1vMCtEUzZZZWM1QXdDRXFWREFLQmdncWhrak9QUVFEQWdOSUFEQkYKQWlFQWs3U3UrV3RmQks4SmVPazRreVFVdEFtMkxoak8zV25qOW5SdW9HbVpyTGdDSUJwdVNnNU5oMjUrYm1xMgpZQ2xEM3NLTGdQM1ZKUitCYytxS3h3UjVHbmJwCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdFkyeHAKWlc1MExXTmhRREUzTXpnNE5UazJNVFl3SGhjTk1qVXdNakEyTVRZek16TTJXaGNOTXpVd01qQTBNVFl6TXpNMgpXakFqTVNFd0h3WURWUVFEREJock0zTXRZMnhwWlc1MExXTmhRREUzTXpnNE5UazJNVFl3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFSTDJSZ1U5RHJZazhKUm4xeDlWSVI3eU5hdWVjaFZuK1pRdDVyeDZaalYKeFRSd0RFT0xXZ1MvbkNpYkp6eUVFNmhLUDVzczBPdnp0ZzlxeFZYU1orNzBvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVWhYcGVaa0xBNHBxTlBnMHVtSG5PClFNQWhLbFF3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUlnS09hYVMyczRSWWgrU3J0TXpXTnVtVHduajlKOTZuWUkKL0prdEhjNU5lQnNDSVFDbTY5a1U3cDA5V3hHYWdkNmRQbUlOQ09Fa2V2bzZoQ0dNQTNpd0ZlZ3BiQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
 | 
					 | 
				
			||||||
    "KUBE_DATA": "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU0yYUxXTmtPQ2ZGRTJxM2V1VE9kaHd0RXdxTWRaVUZTTlRPOG50OER0K1RvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFYkhsU2hUNlF5R1U2ckhFM3hCWkEzeHE3TXRZUE54N1JTZTFkZFlaRnFoZkFhL0pkRloyRgpnK3BLRklzaE9TYlNjVmFUS2tWN2taWXl0NU5qQWRERTZRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo="
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -2,6 +2,9 @@ version: '3.4'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
services:
 | 
					services:
 | 
				
			||||||
  oc-datacenter:
 | 
					  oc-datacenter:
 | 
				
			||||||
 | 
					    env_file:
 | 
				
			||||||
 | 
					    - path: ./env.env
 | 
				
			||||||
 | 
					      required: false
 | 
				
			||||||
    environment: 
 | 
					    environment: 
 | 
				
			||||||
      - MONGO_DATABASE=DC_myDC
 | 
					      - MONGO_DATABASE=DC_myDC
 | 
				
			||||||
    image: 'oc-datacenter:latest'
 | 
					    image: 'oc-datacenter:latest'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,5 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "MONGO_URL":"mongodb://mongo:27017/", 
 | 
					    "MONGO_URL":"mongodb://mongo:27017/", 
 | 
				
			||||||
    "NATS_URL":"nats://nats:4222",
 | 
					    "NATS_URL":"nats://nats:4222",
 | 
				
			||||||
    "MONGO_DATABASE":"DC_myDC",
 | 
					    "MONGO_DATABASE":"DC_myDC"    
 | 
				
			||||||
    "KUBERNETES_SERVICE_HOST" : "172.16.0.181",
 | 
					 | 
				
			||||||
    "KUBE_CA" : "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlRENDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUzTXpnNE5UazJNVFl3SGhjTk1qVXdNakEyTVRZek16TTJXaGNOTXpVd01qQTBNVFl6TXpNMgpXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUzTXpnNE5UazJNVFl3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFSbi9jVmNUb1orekZUdWZSL29qbG5JMnVpZXJYeTkxcWhxYWpHdWVobXYKV1A4NVQ1dXpkcE1rcFhrNnB5bTlFU0RlRjk1WDFkeTJqdjVFR3paZzZ2WWtvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVXJRK0xUR2NMNXBENnBxSEozaVh5CmZiMFRQUDR3Q2dZSUtvWkl6ajBFQXdJRFNRQXdSZ0loQUlObXp3ejhOUVRCNFlURlZJd3BudDhpQjJ5alRlQjYKbkZxRUN6SWw0amUzQWlFQW04dzRma1h0UEhzUG1Yc0hhUXFGSkhkUm9SQ1pSa016akU3REdZY1lMNVE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
 | 
					 | 
				
			||||||
    "KUBE_CERT":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrVENDQVRlZ0F3SUJBZ0lJYVlyeG5xbm54WEl3Q2dZSUtvWkl6ajBFQXdJd0l6RWhNQjhHQTFVRUF3d1kKYXpOekxXTnNhV1Z1ZEMxallVQXhOek00T0RVNU5qRTJNQjRYRFRJMU1ESXdOakUyTXpNek5sb1hEVEkyTURJdwpOakUyTXpNek5sb3dNREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGVEFUQmdOVkJBTVRESE41CmMzUmxiVHBoWkcxcGJqQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJHeDVVb1Ura01obE9xeHgKTjhRV1FOOGF1ekxXRHpjZTBVbnRYWFdHUmFvWHdHdnlYUldkaFlQcVNoU0xJVGttMG5GV2t5cEZlNUdXTXJlVApZd0hReE9talNEQkdNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFmCkJnTlZIU01FR0RBV2dCU0ZlbDVtUXNEaW1vMCtEUzZZZWM1QXdDRXFWREFLQmdncWhrak9QUVFEQWdOSUFEQkYKQWlFQWs3U3UrV3RmQks4SmVPazRreVFVdEFtMkxoak8zV25qOW5SdW9HbVpyTGdDSUJwdVNnNU5oMjUrYm1xMgpZQ2xEM3NLTGdQM1ZKUitCYytxS3h3UjVHbmJwCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdFkyeHAKWlc1MExXTmhRREUzTXpnNE5UazJNVFl3SGhjTk1qVXdNakEyTVRZek16TTJXaGNOTXpVd01qQTBNVFl6TXpNMgpXakFqTVNFd0h3WURWUVFEREJock0zTXRZMnhwWlc1MExXTmhRREUzTXpnNE5UazJNVFl3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFSTDJSZ1U5RHJZazhKUm4xeDlWSVI3eU5hdWVjaFZuK1pRdDVyeDZaalYKeFRSd0RFT0xXZ1MvbkNpYkp6eUVFNmhLUDVzczBPdnp0ZzlxeFZYU1orNzBvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVWhYcGVaa0xBNHBxTlBnMHVtSG5PClFNQWhLbFF3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUlnS09hYVMyczRSWWgrU3J0TXpXTnVtVHduajlKOTZuWUkKL0prdEhjNU5lQnNDSVFDbTY5a1U3cDA5V3hHYWdkNmRQbUlOQ09Fa2V2bzZoQ0dNQTNpd0ZlZ3BiQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
 | 
					 | 
				
			||||||
    "KUBE_DATA": "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU0yYUxXTmtPQ2ZGRTJxM2V1VE9kaHd0RXdxTWRaVUZTTlRPOG50OER0K1RvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFYkhsU2hUNlF5R1U2ckhFM3hCWkEzeHE3TXRZUE54N1JTZTFkZFlaRnFoZkFhL0pkRloyRgpnK3BLRklzaE9TYlNjVmFUS2tWN2taWXl0NU5qQWRERTZRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo="
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										4
									
								
								env.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								env.env
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					KUBERNETES_SERVICE_HOST=192.168.1.169
 | 
				
			||||||
 | 
					KUBE_CA="LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUzTWpNeE1USXdNell3SGhjTk1qUXdPREE0TVRBeE16VTJXaGNOTXpRd09EQTJNVEF4TXpVMgpXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUzTWpNeE1USXdNell3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFTVlk3ZHZhNEdYTVdkMy9jMlhLN3JLYjlnWXgyNSthaEE0NmkyNVBkSFAKRktQL2UxSVMyWVF0dzNYZW1TTUQxaStZdzJSaVppNUQrSVZUamNtNHdhcnFvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVWtlUVJpNFJiODduME5yRnZaWjZHClc2SU55NnN3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUlnRXA5ck04WmdNclRZSHYxZjNzOW5DZXZZeWVVa3lZUk4KWjUzazdoaytJS1FDSVFDbk05TnVGKzlTakIzNDFacGZ5ays2NEpWdkpSM3BhcmVaejdMd2lhNm9kdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
 | 
				
			||||||
 | 
					KUBE_CERT="LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrVENDQVRlZ0F3SUJBZ0lJWUxWNkFPQkdrU1F3Q2dZSUtvWkl6ajBFQXdJd0l6RWhNQjhHQTFVRUF3d1kKYXpOekxXTnNhV1Z1ZEMxallVQXhOekl6TVRFeU1ETTJNQjRYRFRJME1EZ3dPREV3TVRNMU5sb1hEVEkxTURndwpPREV3TVRNMU5sb3dNREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGVEFUQmdOVkJBTVRESE41CmMzUmxiVHBoWkcxcGJqQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJGQ2Q1MFdPeWdlQ2syQzcKV2FrOWY4MVAvSkJieVRIajRWOXBsTEo0ck5HeHFtSjJOb2xROFYxdUx5RjBtOTQ2Nkc0RmRDQ2dqaXFVSk92Swp3NVRPNnd5alNEQkdNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFmCkJnTlZIU01FR0RBV2dCVFJkOFI5cXVWK2pjeUVmL0ovT1hQSzMyS09XekFLQmdncWhrak9QUVFEQWdOSUFEQkYKQWlFQTArbThqTDBJVldvUTZ0dnB4cFo4NVlMalF1SmpwdXM0aDdnSXRxS3NmUVVDSUI2M2ZNdzFBMm5OVWU1TgpIUGZOcEQwSEtwcVN0Wnk4djIyVzliYlJUNklZCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlRENDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdFkyeHAKWlc1MExXTmhRREUzTWpNeE1USXdNell3SGhjTk1qUXdPREE0TVRBeE16VTJXaGNOTXpRd09EQTJNVEF4TXpVMgpXakFqTVNFd0h3WURWUVFEREJock0zTXRZMnhwWlc1MExXTmhRREUzTWpNeE1USXdNell3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFRc3hXWk9pbnIrcVp4TmFEQjVGMGsvTDF5cE01VHAxOFRaeU92ektJazQKRTFsZWVqUm9STW0zNmhPeVljbnN3d3JoNnhSUnBpMW5RdGhyMzg0S0Z6MlBvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVTBYZkVmYXJsZm8zTWhIL3lmemx6Cnl0OWlqbHN3Q2dZSUtvWkl6ajBFQXdJRFNRQXdSZ0loQUxJL2dNYnNMT3MvUUpJa3U2WHVpRVMwTEE2cEJHMXgKcnBlTnpGdlZOekZsQWlFQW1wdjBubjZqN3M0MVI0QzFNMEpSL0djNE53MHdldlFmZWdEVGF1R2p3cFk9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
 | 
				
			||||||
 | 
					KUBE_DATA="LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU5ZS1BFb1dhd1NKUzJlRW5oWmlYMk5VZlY1ZlhKV2krSVNnV09TNFE5VTlvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFVUozblJZN0tCNEtUWUx0WnFUMS96VS84a0Z2Sk1lUGhYMm1Vc25pczBiR3FZblkyaVZEeApYVzR2SVhTYjNqcm9iZ1YwSUtDT0twUWs2OHJEbE03ckRBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo="
 | 
				
			||||||
@@ -16,11 +16,11 @@ type Infrastructure interface {
 | 
				
			|||||||
	CreateRoleBinding(ctx context.Context, ns string, roleBinding string, role string) error
 | 
						CreateRoleBinding(ctx context.Context, ns string, roleBinding string, role string) error
 | 
				
			||||||
	CreateRole(ctx context.Context, ns string, role string, groups [][]string, resources [][]string, verbs [][]string) error
 | 
						CreateRole(ctx context.Context, ns string, role string, groups [][]string, resources [][]string, verbs [][]string) error
 | 
				
			||||||
	GetTargets(ctx context.Context) ([]string,error)
 | 
						GetTargets(ctx context.Context) ([]string,error)
 | 
				
			||||||
	CreateAdmiraltySource(context context.Context,executionId string) ([]byte, error)
 | 
						CreateAdmiraltySource(context context.Context, executionId string) ([]byte, error)
 | 
				
			||||||
	CreateKubeconfigSecret(context context.Context,kubeconfig string, executionId string) ([]byte, error) 
 | 
						CreateKubeconfigSecret(context context.Context, kubeconfig string, executionId string, peerId string) ([]byte, error) 
 | 
				
			||||||
	GetKubeconfigSecret(context context.Context,executionId string) ([]byte, error)
 | 
						GetKubeconfigSecret(context context.Context, executionId string, peerId string) ([]byte, error)
 | 
				
			||||||
	CreateAdmiraltyTarget(context context.Context,executionId string)([]byte,error)
 | 
						CreateAdmiraltyTarget(context context.Context, executionId string, peerId string)([]byte,error)
 | 
				
			||||||
	GetOneNode(context context.Context,executionID string) (*v1.Node, error)
 | 
						GetOneNode(context context.Context, executionID string) (*v1.Node, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var _service = map[string]func() (Infrastructure, error){
 | 
					var _service = map[string]func() (Infrastructure, error){
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,11 @@
 | 
				
			|||||||
package infrastructure
 | 
					package infrastructure
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"encoding/base64"
 | 
						"encoding/base64"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"html/template"
 | 
					 | 
				
			||||||
	"oc-datacenter/conf"
 | 
						"oc-datacenter/conf"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,12 +14,40 @@ import (
 | 
				
			|||||||
	rbacv1 "k8s.io/api/rbac/v1"
 | 
						rbacv1 "k8s.io/api/rbac/v1"
 | 
				
			||||||
	apierrors "k8s.io/apimachinery/pkg/api/errors"
 | 
						apierrors "k8s.io/apimachinery/pkg/api/errors"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/runtime/schema"
 | 
				
			||||||
 | 
						apply "k8s.io/client-go/applyconfigurations/core/v1"
 | 
				
			||||||
 | 
						"k8s.io/client-go/dynamic"
 | 
				
			||||||
	"k8s.io/client-go/kubernetes"
 | 
						"k8s.io/client-go/kubernetes"
 | 
				
			||||||
	"k8s.io/client-go/rest"
 | 
						"k8s.io/client-go/rest"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var gvrSources = schema.GroupVersionResource{Group: "multicluster.admiralty.io", Version: "v1alpha1", Resource: "sources"}
 | 
				
			||||||
 | 
					var gvrTargets = schema.GroupVersionResource{Group: "multicluster.admiralty.io", Version: "v1alpha1", Resource: "targets"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type KubernetesService struct {
 | 
					type KubernetesService struct {
 | 
				
			||||||
	Set *kubernetes.Clientset
 | 
						Set 			*kubernetes.Clientset
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewDynamicClient() (*dynamic.DynamicClient, error) {
 | 
				
			||||||
 | 
						config := &rest.Config{
 | 
				
			||||||
 | 
							Host: conf.GetConfig().KubeHost + ":" + conf.GetConfig().KubePort,
 | 
				
			||||||
 | 
							TLSClientConfig: rest.TLSClientConfig{
 | 
				
			||||||
 | 
								CAData:   []byte(conf.GetConfig().KubeCA),
 | 
				
			||||||
 | 
								CertData: []byte(conf.GetConfig().KubeCert),
 | 
				
			||||||
 | 
								KeyData:  []byte(conf.GetConfig().KubeData),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dynamicClient, err := dynamic.NewForConfig(config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, errors.New("Error creating Dynamic client: " + err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dynamicClient == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("Error creating Dynamic client: dynamicClient is nil")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dynamicClient, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewKubernetesService() (Infrastructure, error) {
 | 
					func NewKubernetesService() (Infrastructure, error) {
 | 
				
			||||||
@@ -33,6 +59,7 @@ func NewKubernetesService() (Infrastructure, error) {
 | 
				
			|||||||
			KeyData:  []byte(conf.GetConfig().KubeData),
 | 
								KeyData:  []byte(conf.GetConfig().KubeData),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	// Create clientset
 | 
						// Create clientset
 | 
				
			||||||
	clientset, err := kubernetes.NewForConfig(config)
 | 
						clientset, err := kubernetes.NewForConfig(config)
 | 
				
			||||||
	fmt.Println("NewForConfig", clientset, err)
 | 
						fmt.Println("NewForConfig", clientset, err)
 | 
				
			||||||
@@ -43,6 +70,7 @@ func NewKubernetesService() (Infrastructure, error) {
 | 
				
			|||||||
		return nil, errors.New("Error creating Kubernetes client: clientset is nil")
 | 
							return nil, errors.New("Error creating Kubernetes client: clientset is nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &KubernetesService{
 | 
						return &KubernetesService{
 | 
				
			||||||
		Set: clientset,
 | 
							Set: clientset,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
@@ -82,6 +110,9 @@ func (k *KubernetesService) CreateNamespace(ctx context.Context, ns string) erro
 | 
				
			|||||||
	namespace := &v1.Namespace{
 | 
						namespace := &v1.Namespace{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{
 | 
							ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
			Name: ns,
 | 
								Name: ns,
 | 
				
			||||||
 | 
								Labels: map[string]string{
 | 
				
			||||||
 | 
									"multicluster-scheduler":"enabled",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Create the namespace
 | 
						// Create the namespace
 | 
				
			||||||
@@ -195,27 +226,25 @@ func (k *KubernetesService) GenerateToken(ctx context.Context, ns string, durati
 | 
				
			|||||||
	return token.Status.Token, nil
 | 
						return token.Status.Token, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Needs refactoring :
 | 
					// Needs refactoring :
 | 
				
			||||||
//  - Retrieving the metada (in a method that Unmarshall the part of the json in a metadata object)
 | 
					//   - Retrieving the metada (in a method that Unmarshall the part of the json in a metadata object)
 | 
				
			||||||
func (k *KubernetesService) GetTargets(ctx context.Context) ([]string,error){
 | 
					func (k *KubernetesService) GetTargets(ctx context.Context) ([]string, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var listTargets []string
 | 
						var listTargets []string
 | 
				
			||||||
	resp, err := getCDRapiKube(*k.Set, ctx,"/apis/multicluster.admiralty.io/v1alpha1/targets")
 | 
						resp, err := getCDRapiKube(*k.Set, ctx, "/apis/multicluster.admiralty.io/v1alpha1/targets")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil,err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Println(string(resp))
 | 
						fmt.Println(string(resp))
 | 
				
			||||||
	var targetDict map[string]interface{}
 | 
						var targetDict map[string]interface{}
 | 
				
			||||||
	err = json.Unmarshal(resp,&targetDict)
 | 
						err = json.Unmarshal(resp, &targetDict)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("TODO: handle the error when unmarshalling k8s API response")
 | 
							fmt.Println("TODO: handle the error when unmarshalling k8s API response")
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b, _ := json.MarshalIndent(targetDict,""," ")
 | 
						b, _ := json.MarshalIndent(targetDict, "", " ")
 | 
				
			||||||
	fmt.Println(string(b))
 | 
						fmt.Println(string(b))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data := targetDict["items"].([]interface{})
 | 
						data := targetDict["items"].([]interface{})
 | 
				
			||||||
@@ -224,25 +253,25 @@ func (k *KubernetesService) GetTargets(ctx context.Context) ([]string,error){
 | 
				
			|||||||
		var metadata metav1.ObjectMeta
 | 
							var metadata metav1.ObjectMeta
 | 
				
			||||||
		item := item.(map[string]interface{})
 | 
							item := item.(map[string]interface{})
 | 
				
			||||||
		byteMetada, err := json.Marshal(item["metadata"])
 | 
							byteMetada, err := json.Marshal(item["metadata"])
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			fmt.Println("Error while Marshalling metadata field")
 | 
								fmt.Println("Error while Marshalling metadata field")
 | 
				
			||||||
			return nil,err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		err = json.Unmarshal(byteMetada,&metadata)
 | 
							err = json.Unmarshal(byteMetada, &metadata)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			fmt.Println("Error while Unmarshalling metadata field to the library object")
 | 
								fmt.Println("Error while Unmarshalling metadata field to the library object")
 | 
				
			||||||
			return nil,err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		listTargets = append(listTargets, metadata.Name)
 | 
							listTargets = append(listTargets, metadata.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return listTargets,nil
 | 
						return listTargets, nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Admiralty Target allows a cluster to deploy pods to remote cluster 
 | 
					// Admiralty Target allows a cluster to deploy pods to remote cluster
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// The remote  cluster must :
 | 
					// The remote  cluster must :
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -250,48 +279,46 @@ func (k *KubernetesService) GetTargets(ctx context.Context) ([]string,error){
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// - have declared the same namespace as the one where the pods are created in the local cluster
 | 
					// - have declared the same namespace as the one where the pods are created in the local cluster
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// - have delcared a serviceAccount with sufficient permission to create pods 
 | 
					// - have delcared a serviceAccount with sufficient permission to create pods
 | 
				
			||||||
func (k *KubernetesService) CreateAdmiraltyTarget(context context.Context,executionId string)([]byte,error){
 | 
					func (k *KubernetesService) CreateAdmiraltyTarget(context context.Context, executionId string, peerId string) ([]byte, error) {
 | 
				
			||||||
	exists, err := k.GetKubeconfigSecret(context,executionId)
 | 
						exists, err := k.GetKubeconfigSecret(context, executionId, peerId)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error verifying kube-secret before creating target")
 | 
							fmt.Println("Error verifying kube-secret before creating target")
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if exists == nil {
 | 
						if exists == nil {
 | 
				
			||||||
		fmt.Println("Target needs to be binded to a secret in namespace ",executionId)
 | 
							fmt.Println("Target needs to be binded to a secret in namespace ", executionId)
 | 
				
			||||||
		return nil, nil	// Maybe we could create a wrapper for errors and add more info to have
 | 
							return nil, nil // Maybe we could create a wrapper for errors and add more info to have
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	var targetManifest string 
 | 
						targetName := "target-" + getConcatenatedName(peerId,executionId)
 | 
				
			||||||
	var tpl bytes.Buffer
 | 
						target := map[string]interface{}{
 | 
				
			||||||
	tmpl, err := template.New("target").
 | 
					        "apiVersion": "multicluster.admiralty.io/v1alpha1",
 | 
				
			||||||
		Parse("{\"apiVersion\": \"multicluster.admiralty.io/v1alpha1\", \"kind\": \"Target\", \"metadata\": {\"name\": \"target-{{.ExecutionId}}\"}, \"spec\": { \"kubeconfigSecret\" :{\"name\": \"kube-secret-{{.ExecutionId}}\"}} }")
 | 
					        "kind":       "Target",
 | 
				
			||||||
 | 
					        "metadata": map[string]interface{}{
 | 
				
			||||||
 | 
					            "name":       targetName,
 | 
				
			||||||
 | 
					            "namespace": executionId,
 | 
				
			||||||
 | 
								"labels": map[string]interface{}{
 | 
				
			||||||
 | 
									"peer": peerId,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "spec": map[string]interface{}{
 | 
				
			||||||
 | 
					            "kubeconfigSecret": map[string]string{
 | 
				
			||||||
 | 
									"name" : "kube-secret-"+ getConcatenatedName(peerId, executionId),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res, err := dynamicClientApply(executionId, targetName, gvrTargets, context, target)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error creating the template for the target Manifest")
 | 
							return nil, errors.New("Error when trying to apply Target definition :" + err.Error())
 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = tmpl.Execute(&tpl, map[string]string{"ExecutionId":executionId})
 | 
						return res, nil
 | 
				
			||||||
	targetManifest = tpl.String()
 | 
					 | 
				
			||||||
	resp, err := postCDRapiKube(
 | 
					 | 
				
			||||||
		*k.Set,
 | 
					 | 
				
			||||||
		context,
 | 
					 | 
				
			||||||
		"/apis/multicluster.admiralty.io/v1alpha1/namespaces/"+ executionId +"/targets",
 | 
					 | 
				
			||||||
		[]byte(targetManifest),
 | 
					 | 
				
			||||||
		map[string]string{"fieldManager":"kubectl-client-side-apply"},
 | 
					 | 
				
			||||||
		map[string]string{"fieldValidation":"Strict"},
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", resp)
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return resp, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
// Admiralty Source allows a cluster to receive pods from a remote cluster
 | 
					// Admiralty Source allows a cluster to receive pods from a remote cluster
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// The source must be associated to a serviceAccount, which will execute the pods locally.
 | 
					// The source must be associated to a serviceAccount, which will execute the pods locally.
 | 
				
			||||||
@@ -301,39 +328,31 @@ func (k *KubernetesService) CreateAdmiraltyTarget(context context.Context,execut
 | 
				
			|||||||
// to rather contact the oc-datacenter from the remote cluster to create the source
 | 
					// to rather contact the oc-datacenter from the remote cluster to create the source
 | 
				
			||||||
// locally and retrieve the token for the serviceAccount
 | 
					// locally and retrieve the token for the serviceAccount
 | 
				
			||||||
func (k *KubernetesService) CreateAdmiraltySource(context context.Context,executionId string) ([]byte, error) {
 | 
					func (k *KubernetesService) CreateAdmiraltySource(context context.Context,executionId string) ([]byte, error) {
 | 
				
			||||||
	var sourceManifest string 
 | 
					
 | 
				
			||||||
	var tpl bytes.Buffer
 | 
						source := map[string]interface{}{
 | 
				
			||||||
	tmpl, err := template.New("source").
 | 
					        "apiVersion": "multicluster.admiralty.io/v1alpha1",
 | 
				
			||||||
		Parse("{\"apiVersion\": \"multicluster.admiralty.io/v1alpha1\", \"kind\": \"Source\", \"metadata\": {\"name\": \"source-{{.ExecutionId}}\"}, \"spec\": {\"serviceAccountName\": \"sa-{{.ExecutionId}}\"} }")
 | 
					        "kind":       "Source",
 | 
				
			||||||
 | 
					        "metadata": map[string]interface{}{
 | 
				
			||||||
 | 
					            "name":      "source-"+executionId,
 | 
				
			||||||
 | 
					            "namespace": executionId,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "spec": map[string]interface{}{
 | 
				
			||||||
 | 
					            "serviceAccountName": "sa-"+executionId,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res, err := dynamicClientApply(executionId, "source-" + executionId,gvrSources, context, source)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error creating the template for the source Manifest")
 | 
							return nil, errors.New("Error when trying to apply Source definition :" + err.Error())
 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = tmpl.Execute(&tpl, map[string]string{"ExecutionId":executionId})
 | 
						return res, nil
 | 
				
			||||||
	sourceManifest = tpl.String()
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	resp, err := postCDRapiKube(
 | 
					 | 
				
			||||||
		*k.Set,
 | 
					 | 
				
			||||||
		context,
 | 
					 | 
				
			||||||
		"/apis/multicluster.admiralty.io/v1alpha1/namespaces/"+ executionId +"/sources",
 | 
					 | 
				
			||||||
		[]byte(sourceManifest),
 | 
					 | 
				
			||||||
		map[string]string{"fieldManager":"kubectl-client-side-apply"},
 | 
					 | 
				
			||||||
		map[string]string{"fieldValidation":"Strict"},
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// We can add more info to the log with the content of resp if not nil
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", resp)
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return resp, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create a secret from a kubeconfing. Use it to create the secret binded to an Admiralty
 | 
					// Create a secret from a kubeconfing. Use it to create the secret binded to an Admiralty
 | 
				
			||||||
// target, which must contain the serviceAccount's token value
 | 
					// target, which must contain the serviceAccount's token value
 | 
				
			||||||
func (k *KubernetesService) CreateKubeconfigSecret(context context.Context,kubeconfig string, executionId string) ([]byte, error) {
 | 
					func (k *KubernetesService) CreateKubeconfigSecret(context context.Context, kubeconfig string, executionId string, peerId string) ([]byte, error) {
 | 
				
			||||||
	config, err := base64.StdEncoding.DecodeString(kubeconfig)
 | 
						config, err := base64.StdEncoding.DecodeString(kubeconfig)
 | 
				
			||||||
	// config, err := base64.RawStdEncoding.DecodeString(kubeconfig)
 | 
						// config, err := base64.RawStdEncoding.DecodeString(kubeconfig)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -342,35 +361,40 @@ func (k *KubernetesService) CreateKubeconfigSecret(context context.Context,kubec
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	secretManifest := &v1.Secret{
 | 
						secretApplyConfig := apply.Secret("kube-secret-" + getConcatenatedName(peerId, executionId),
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{
 | 
														executionId).
 | 
				
			||||||
			Name:      "kube-secret-" + executionId,
 | 
													WithData(map[string][]byte{
 | 
				
			||||||
			Namespace:  executionId,
 | 
															"config": config,
 | 
				
			||||||
		},
 | 
															},
 | 
				
			||||||
		Data: map[string][]byte{
 | 
														)
 | 
				
			||||||
			"config": config,
 | 
					
 | 
				
			||||||
		},
 | 
					
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
						// exists, err := k.GetKubeconfigSecret(context,executionId)
 | 
				
			||||||
 | 
						// if err != nil {
 | 
				
			||||||
 | 
						// 	fmt.Println("Error verifying if kube secret exists in namespace ", executionId)
 | 
				
			||||||
 | 
						// 	return nil, err
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
						// if exists != nil {
 | 
				
			||||||
 | 
						// 	fmt.Println("kube-secret already exists in namespace", executionId)
 | 
				
			||||||
 | 
						// 	fmt.Println("Overriding existing kube-secret with a newer resource")
 | 
				
			||||||
 | 
						// 	// TODO : implement DeleteKubeConfigSecret(executionID)
 | 
				
			||||||
 | 
						// 	deleted, err := k.DeleteKubeConfigSecret(executionId)
 | 
				
			||||||
 | 
						// 	_ = deleted
 | 
				
			||||||
 | 
						// 	_ = err
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	exists, err := k.GetKubeconfigSecret(context,executionId)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		fmt.Println("Error verifying if kube secret exists in namespace ", executionId)
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if exists != nil {
 | 
					 | 
				
			||||||
		fmt.Println("kube-secret already exists in namespace", executionId)
 | 
					 | 
				
			||||||
		fmt.Println("Overriding existing kube-secret with a newer resource")
 | 
					 | 
				
			||||||
		// TODO : implement DeleteKubeConfigSecret(executionID)
 | 
					 | 
				
			||||||
		deleted, err := k.DeleteKubeConfigSecret(executionId)
 | 
					 | 
				
			||||||
		_ = deleted
 | 
					 | 
				
			||||||
		_ = err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resp, err := k.Set.CoreV1().
 | 
						resp, err := k.Set.CoreV1().
 | 
				
			||||||
				Secrets(executionId).
 | 
									Secrets(executionId).
 | 
				
			||||||
				Create(context,secretManifest,metav1.CreateOptions{})
 | 
									Apply(context,
 | 
				
			||||||
 | 
										secretApplyConfig,
 | 
				
			||||||
 | 
										metav1.ApplyOptions{
 | 
				
			||||||
 | 
											FieldManager: "admiralty-manager",
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error while trying to contact API to get secret kube-secret-"+executionId)
 | 
							fmt.Println("Error while trying to contact API to get secret kube-secret-" + executionId)
 | 
				
			||||||
		fmt.Println(err)
 | 
							fmt.Println(err)
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -382,19 +406,19 @@ func (k *KubernetesService) CreateKubeconfigSecret(context context.Context,kubec
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return data, nil
 | 
						return data, nil
 | 
				
			||||||
} 
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (k *KubernetesService) GetKubeconfigSecret(context context.Context,executionId string) ([]byte, error) {
 | 
					func (k *KubernetesService) GetKubeconfigSecret(context context.Context, executionId string, peerId string) ([]byte, error) {
 | 
				
			||||||
	resp, err := k.Set.CoreV1().
 | 
						resp, err := k.Set.CoreV1().
 | 
				
			||||||
						Secrets(executionId).
 | 
							Secrets(executionId).
 | 
				
			||||||
						Get(context,"kube-secret-"+executionId,metav1.GetOptions{})
 | 
							Get(context, "kube-secret-"+ getConcatenatedName(peerId, executionId), metav1.GetOptions{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if(apierrors.IsNotFound(err)){
 | 
							if apierrors.IsNotFound(err) {
 | 
				
			||||||
			fmt.Println("kube-secret not found for execution", executionId)
 | 
								fmt.Println("kube-secret not found for execution", executionId)
 | 
				
			||||||
			return nil, nil
 | 
								return nil, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fmt.Println("Error while trying to contact API to get secret kube-secret-"+executionId)
 | 
							fmt.Println("Error while trying to contact API to get secret kube-secret-" + executionId)
 | 
				
			||||||
		fmt.Println(err)
 | 
							fmt.Println(err)
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -410,41 +434,74 @@ func (k *KubernetesService) GetKubeconfigSecret(context context.Context,executio
 | 
				
			|||||||
	return data, nil
 | 
						return data, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (k *KubernetesService) DeleteKubeConfigSecret(executionID string) ([]byte, error){
 | 
					func (k *KubernetesService) DeleteKubeConfigSecret(executionID string) ([]byte, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return []byte{}, nil
 | 
						return []byte{}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getCDRapiKube(client kubernetes.Clientset, ctx context.Context, path string) ([]byte,error) {
 | 
					func getCDRapiKube(client kubernetes.Clientset, ctx context.Context, path string) ([]byte, error) {
 | 
				
			||||||
	resp, err := client.RESTClient().Get().
 | 
						resp, err := client.RESTClient().Get().
 | 
				
			||||||
	AbsPath(path).
 | 
							AbsPath(path).
 | 
				
			||||||
	DoRaw(ctx) // from https://stackoverflow.com/questions/60764908/how-to-access-kubernetes-crd-using-client-go
 | 
							DoRaw(ctx) // from https://stackoverflow.com/questions/60764908/how-to-access-kubernetes-crd-using-client-go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error from k8s API when getting " + path + " : " , err)
 | 
							fmt.Println("Error from k8s API when getting "+path+" : ", err)
 | 
				
			||||||
		return nil,err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return resp, nil
 | 
						return resp, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func postCDRapiKube(client kubernetes.Clientset, ctx context.Context, path string, body []byte, params ...map[string]string) ([]byte, error){
 | 
					func dynamicClientApply(executionId string, resourceName string, resourceDefinition schema.GroupVersionResource, ctx context.Context, object map[string]interface{}) ([]byte, error) {
 | 
				
			||||||
 | 
						cli, err := NewDynamicClient()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, errors.New("Could not retrieve dynamic client when creating Admiralty Source : " + err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res, err := cli.Resource(resourceDefinition).
 | 
				
			||||||
 | 
									Namespace(executionId).
 | 
				
			||||||
 | 
									Apply(ctx, 
 | 
				
			||||||
 | 
										resourceName,
 | 
				
			||||||
 | 
										&unstructured.Unstructured{Object: object},
 | 
				
			||||||
 | 
										metav1.ApplyOptions{
 | 
				
			||||||
 | 
											FieldManager: "kubectl-client-side-apply", 
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							o, err := json.Marshal(object)
 | 
				
			||||||
 | 
							fmt.Println("Error from k8s API when applying " + fmt.Sprint(string(o)) + " to " + gvrSources.String() + " : " , err)
 | 
				
			||||||
 | 
							return nil,err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We can add more info to the log with the content of resp if not nil
 | 
				
			||||||
 | 
						resByte, err := json.Marshal(res) 
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							// fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", res)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return resByte, nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func putCDRapiKube(client kubernetes.Clientset, ctx context.Context, path string, body []byte, params ...map[string]string) ([]byte, error){
 | 
				
			||||||
	req := client.RESTClient().
 | 
						req := client.RESTClient().
 | 
				
			||||||
				Post().
 | 
							Post().
 | 
				
			||||||
				AbsPath(path).
 | 
							AbsPath(path).
 | 
				
			||||||
				Body(body)
 | 
							Body(body)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, param := range params {
 | 
						for _, param := range params {
 | 
				
			||||||
		for k,v := range param {
 | 
							for k, v := range param {
 | 
				
			||||||
			req = req.Param(k,v)
 | 
								req = req.Param(k, v)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	resp, err := req.DoRaw(ctx)
 | 
						resp, err := req.DoRaw(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error from k8s API when posting " + string(body) + " to " + path + " : " , err)
 | 
							fmt.Println("Error from k8s API when posting "+string(body)+" to "+path+" : ", err)
 | 
				
			||||||
		return nil,err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return resp, nil
 | 
						return resp, nil
 | 
				
			||||||
@@ -453,13 +510,13 @@ func postCDRapiKube(client kubernetes.Clientset, ctx context.Context, path strin
 | 
				
			|||||||
// Returns the Kubernetes' Node object corresponding to the executionID if it exists on this host
 | 
					// Returns the Kubernetes' Node object corresponding to the executionID if it exists on this host
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// The node is created when an admiralty Target (on host) can connect to an admiralty Source (on remote)
 | 
					// The node is created when an admiralty Target (on host) can connect to an admiralty Source (on remote)
 | 
				
			||||||
func (k *KubernetesService) GetOneNode(context context.Context,executionID string) (*v1.Node, error) {
 | 
					func (k *KubernetesService) GetOneNode(context context.Context, executionID string) (*v1.Node, error) {
 | 
				
			||||||
	res, err := k.Set.CoreV1().
 | 
						res, err := k.Set.CoreV1().
 | 
				
			||||||
						Nodes().
 | 
							Nodes().
 | 
				
			||||||
						List(
 | 
							List(
 | 
				
			||||||
							context, 
 | 
								context,
 | 
				
			||||||
							metav1.ListOptions{},
 | 
								metav1.ListOptions{},
 | 
				
			||||||
						)
 | 
							)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error getting the list of nodes from k8s API")
 | 
							fmt.Println("Error getting the list of nodes from k8s API")
 | 
				
			||||||
		fmt.Println(err)
 | 
							fmt.Println(err)
 | 
				
			||||||
@@ -467,10 +524,21 @@ func (k *KubernetesService) GetOneNode(context context.Context,executionID strin
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, node := range res.Items {
 | 
						for _, node := range res.Items {
 | 
				
			||||||
		if isNode := strings.Contains(node.Name,"admiralty-"+executionID+"-target-"+executionID+"-"); isNode {
 | 
							if isNode := strings.Contains(node.Name, "admiralty-"+executionID+"-target-"+executionID+"-"); isNode {
 | 
				
			||||||
			return &node, nil
 | 
								return &node, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Returns a concatenation of the peerId and namespace in order for
 | 
				
			||||||
 | 
					// kubernetes ressources to have a unique name, under 63 characters
 | 
				
			||||||
 | 
					// and yet identify which peer they are created for
 | 
				
			||||||
 | 
					func getConcatenatedName(peerId string, namespace string) string {
 | 
				
			||||||
 | 
						s := strings.Split(peerId, "-")[:2]
 | 
				
			||||||
 | 
						p := s[0] + "-" + s[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return p + "-" + namespace
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								main.go
									
									
									
									
									
								
							@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"encoding/base64"
 | 
						"encoding/base64"
 | 
				
			||||||
	"oc-datacenter/conf"
 | 
						"oc-datacenter/conf"
 | 
				
			||||||
	_ "oc-datacenter/routers"
 | 
						_ "oc-datacenter/routers"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	oclib "cloud.o-forge.io/core/oc-lib"
 | 
						oclib "cloud.o-forge.io/core/oc-lib"
 | 
				
			||||||
	"cloud.o-forge.io/core/oc-lib/tools"
 | 
						"cloud.o-forge.io/core/oc-lib/tools"
 | 
				
			||||||
@@ -20,7 +21,7 @@ func main() {
 | 
				
			|||||||
	// Load the right config file
 | 
						// Load the right config file
 | 
				
			||||||
	o := oclib.GetConfLoader()
 | 
						o := oclib.GetConfLoader()
 | 
				
			||||||
	conf.GetConfig().Mode = o.GetStringDefault("MODE", "kubernetes")
 | 
						conf.GetConfig().Mode = o.GetStringDefault("MODE", "kubernetes")
 | 
				
			||||||
	conf.GetConfig().KubeHost = o.GetStringDefault("KUBERNETES_SERVICE_HOST", "")
 | 
						conf.GetConfig().KubeHost = o.GetStringDefault("KUBERNETES_SERVICE_HOST", os.Getenv("KUBERNETES_SERVICE_HOST"))
 | 
				
			||||||
	conf.GetConfig().KubePort = o.GetStringDefault("KUBERNETES_SERVICE_PORT", "6443")
 | 
						conf.GetConfig().KubePort = o.GetStringDefault("KUBERNETES_SERVICE_PORT", "6443")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sDec, err := base64.StdEncoding.DecodeString(o.GetStringDefault("KUBE_CA", ""))
 | 
						sDec, err := base64.StdEncoding.DecodeString(o.GetStringDefault("KUBE_CA", ""))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ func init() {
 | 
				
			|||||||
    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
					    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
				
			||||||
        beego.ControllerComments{
 | 
					        beego.ControllerComments{
 | 
				
			||||||
            Method: "GetNodeReady",
 | 
					            Method: "GetNodeReady",
 | 
				
			||||||
            Router: `/node/:execution`,
 | 
					            Router: `/node/:execution/:peer`,
 | 
				
			||||||
            AllowHTTPMethods: []string{"get"},
 | 
					            AllowHTTPMethods: []string{"get"},
 | 
				
			||||||
            MethodParams: param.Make(),
 | 
					            MethodParams: param.Make(),
 | 
				
			||||||
            Filters: nil,
 | 
					            Filters: nil,
 | 
				
			||||||
@@ -28,7 +28,7 @@ func init() {
 | 
				
			|||||||
    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
					    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
				
			||||||
        beego.ControllerComments{
 | 
					        beego.ControllerComments{
 | 
				
			||||||
            Method: "GetKubeSecret",
 | 
					            Method: "GetKubeSecret",
 | 
				
			||||||
            Router: `/secret/:execution`,
 | 
					            Router: `/secret/:execution/:peer`,
 | 
				
			||||||
            AllowHTTPMethods: []string{"get"},
 | 
					            AllowHTTPMethods: []string{"get"},
 | 
				
			||||||
            MethodParams: param.Make(),
 | 
					            MethodParams: param.Make(),
 | 
				
			||||||
            Filters: nil,
 | 
					            Filters: nil,
 | 
				
			||||||
@@ -37,7 +37,7 @@ func init() {
 | 
				
			|||||||
    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
					    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
				
			||||||
        beego.ControllerComments{
 | 
					        beego.ControllerComments{
 | 
				
			||||||
            Method: "CreateKubeSecret",
 | 
					            Method: "CreateKubeSecret",
 | 
				
			||||||
            Router: `/secret/:execution`,
 | 
					            Router: `/secret/:execution/:peer`,
 | 
				
			||||||
            AllowHTTPMethods: []string{"post"},
 | 
					            AllowHTTPMethods: []string{"post"},
 | 
				
			||||||
            MethodParams: param.Make(),
 | 
					            MethodParams: param.Make(),
 | 
				
			||||||
            Filters: nil,
 | 
					            Filters: nil,
 | 
				
			||||||
@@ -45,7 +45,7 @@ func init() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
					    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
				
			||||||
        beego.ControllerComments{
 | 
					        beego.ControllerComments{
 | 
				
			||||||
            Method: "CreateSource",
 | 
					            Method: "CreateAdmiraltySource",
 | 
				
			||||||
            Router: `/source/:execution`,
 | 
					            Router: `/source/:execution`,
 | 
				
			||||||
            AllowHTTPMethods: []string{"post"},
 | 
					            AllowHTTPMethods: []string{"post"},
 | 
				
			||||||
            MethodParams: param.Make(),
 | 
					            MethodParams: param.Make(),
 | 
				
			||||||
@@ -55,7 +55,7 @@ func init() {
 | 
				
			|||||||
    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
					    beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
 | 
				
			||||||
        beego.ControllerComments{
 | 
					        beego.ControllerComments{
 | 
				
			||||||
            Method: "CreateAdmiraltyTarget",
 | 
					            Method: "CreateAdmiraltyTarget",
 | 
				
			||||||
            Router: `/target/:execution`,
 | 
					            Router: `/target/:execution/:peer`,
 | 
				
			||||||
            AllowHTTPMethods: []string{"post"},
 | 
					            AllowHTTPMethods: []string{"post"},
 | 
				
			||||||
            MethodParams: param.Make(),
 | 
					            MethodParams: param.Make(),
 | 
				
			||||||
            Filters: nil,
 | 
					            Filters: nil,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user