Skip to content

feat:shifted gRPC call of cluster and repo creation to Argo REST api call #3325

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,15 +324,16 @@ func InitializeApp() (*App, error) {
restHandler.NewCDRestHandlerImpl,
wire.Bind(new(restHandler.CDRestHandler), new(*restHandler.CDRestHandlerImpl)),

ArgoUtil.GetArgoConfig,
//ArgoUtil.GetArgoConfig,
ArgoUtil.NewArgoSession,
ArgoUtil.NewResourceServiceImpl,
wire.Bind(new(ArgoUtil.ResourceService), new(*ArgoUtil.ResourceServiceImpl)),
//ArgoUtil.NewApplicationServiceImpl,
//wire.Bind(new(ArgoUtil.ApplicationService), new(ArgoUtil.ApplicationServiceImpl)),
//ArgoUtil.NewRepositoryService,
//wire.Bind(new(ArgoUtil.RepositoryService), new(ArgoUtil.RepositoryServiceImpl)),

ArgoUtil.NewRepositoryService,
wire.Bind(new(ArgoUtil.RepositoryService), new(*ArgoUtil.RepositoryServiceImpl)),
ArgoUtil.NewArgoClusterServiceImpl,
wire.Bind(new(ArgoUtil.ArgoClusterService), new(*ArgoUtil.ArgoClusterServiceImpl)),
pipelineConfig.NewDbMigrationConfigRepositoryImpl,
wire.Bind(new(pipelineConfig.DbMigrationConfigRepository), new(*pipelineConfig.DbMigrationConfigRepositoryImpl)),
pipeline.NewDbConfigService,
Expand Down
4 changes: 3 additions & 1 deletion api/appStore/deployment/AppStoreDeploymentRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,11 @@ func (handler AppStoreDeploymentRestHandlerImpl) InstallApp(w http.ResponseWrite
}
}(ctx.Done(), cn.CloseNotify())
}
acdToken := ""
if util2.IsBaseStack() || util2.IsHelmApp(request.AppOfferingMode) {
ctx = context.WithValue(r.Context(), "token", token)
} else {
acdToken, err := handler.argoUserService.GetLatestDevtronArgoCdUserToken()
acdToken, err = handler.argoUserService.GetLatestDevtronArgoCdUserToken()
if err != nil {
handler.Logger.Errorw("error in getting acd token", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
Expand All @@ -174,6 +175,7 @@ func (handler AppStoreDeploymentRestHandlerImpl) InstallApp(w http.ResponseWrite
}

defer cancel()
request.AcdToken = acdToken
res, err := handler.appStoreDeploymentService.InstallApp(&request, ctx)
if err != nil {
if strings.Contains(err.Error(), "application spec is invalid") {
Expand Down
5 changes: 3 additions & 2 deletions api/cluster/ClusterRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,19 @@ func (impl ClusterRestHandlerImpl) Save(w http.ResponseWriter, r *http.Request)
}
}(ctx.Done(), cn.CloseNotify())
}
acdToken := ""
if util2.IsBaseStack() {
ctx = context.WithValue(ctx, "token", token)
} else {
acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken()
acdToken, err = impl.argoUserService.GetLatestDevtronArgoCdUserToken()
if err != nil {
impl.logger.Errorw("error in getting acd token", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
ctx = context.WithValue(ctx, "token", acdToken)
}
bean, err = impl.clusterService.Save(ctx, bean, userId)
bean, err = impl.clusterService.Save(ctx, bean, userId, acdToken)
if err != nil {
impl.logger.Errorw("service err, Save", "err", err, "payload", bean)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
Expand Down
1 change: 1 addition & 0 deletions api/restHandler/app/DeploymentPipelineRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ func (handler PipelineConfigRestHandlerImpl) CreateCdPipeline(w http.ResponseWri
}
//RBAC
acdToken, err := handler.argoUserService.GetLatestDevtronArgoCdUserToken()
cdPipeline.AcdToken = acdToken
if err != nil {
handler.Logger.Errorw("error in getting acd token", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
Expand Down
116 changes: 92 additions & 24 deletions internal/util/ArgoUtil/ArgoClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package ArgoUtil

import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"github.com/caarlos0/env"
Expand All @@ -43,6 +44,28 @@ type ArgoSession struct {
logger *zap.SugaredLogger
baseUrl *url.URL
}

func NewArgoSession(httpClient *http.Client, logger *zap.SugaredLogger) *ArgoSession {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
cfg, err := GetArgoConfig()
if err != nil {
return nil
}
baseUrl := &url.URL{
Scheme: "https",
Host: cfg.Url,
}

client := &http.Client{Transport: tr}
return &ArgoSession{
httpClient: client,
logger: logger,
baseUrl: baseUrl,
}
}

type StatusCode int

func (code StatusCode) IsSuccess() bool {
Expand Down Expand Up @@ -106,34 +129,79 @@ func (session *ArgoSession) DoRequest(clientRequest *ClientRequest) (resBody []b
}
return resBody, &status, err
}

func NewArgoSession(config *ArgoConfig, logger *zap.SugaredLogger) (session *ArgoSession, err error) {
/*location := "/api/v1/session"
baseUrl, err := url.Parse(config.Url)
func (session *ArgoSession) DoRequestForArgo(clientRequest *ClientRequest, acdToken string) (resBody []byte, resCode *StatusCode, err error) {
if clientRequest.ResponseBody == nil {
return nil, nil, fmt.Errorf("response body cant be nil")
}
if reflect.ValueOf(clientRequest.ResponseBody).Kind() != reflect.Ptr {
return nil, nil, fmt.Errorf("responsebody non pointer")
}
rel, err := session.baseUrl.Parse(clientRequest.Path)
if err != nil {
return nil, err
return nil, nil, err
}
rel, err := baseUrl.Parse(location)
param := map[string]string{}
param["username"] = "admin"
param["password"] = "argocd-server-6cd5bcffd4-j6kcx"
paramJson, err := json.Marshal(param)
var body io.Reader
if clientRequest.RequestBody != nil {
if req, err := json.Marshal(clientRequest.RequestBody); err != nil {
return nil, nil, err
} else {
session.logger.Debugw("argo req with body", "body", string(req))
body = bytes.NewBuffer(req)
}
}
httpReq, err := http.NewRequest("POST", rel.String(), body)
if err != nil {
return nil, err
return nil, nil, err
}
req, _ := http.NewRequest("POST", rel.String(), bytes.NewBuffer(paramJson))
transCfg := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify},
httpReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", acdToken))
httpReq.Header.Set("Content-Type", "application/json")
httpRes, err := session.httpClient.Do(httpReq)
if err != nil {
return nil, nil, err
}
cookieJar, err := cookiejar.New(nil)
defer httpRes.Body.Close()
resBody, err = ioutil.ReadAll(httpRes.Body)
if err != nil {
return nil, err
}
client := &http.Client{Transport: transCfg, Jar: cookieJar, Timeout: time.Duration(config.Timeout)}
res, err := client.Do(req)
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, err
}*/
return &ArgoSession{}, nil
session.logger.Errorw("error in argocd communication ", "err", err)
return nil, nil, err
}
status := StatusCode(httpRes.StatusCode)
if status.IsSuccess() {
err = json.Unmarshal(resBody, clientRequest.ResponseBody)
} else {
session.logger.Errorw("api err", "res", string(resBody))
return resBody, &status, fmt.Errorf("res not success, code: %d ", status)
}
return resBody, &status, err
}

//func NewArgoSession(config *ArgoConfig, logger *zap.SugaredLogger) (session *ArgoSession, err error) {
// /*location := "/api/v1/session"
// baseUrl, err := url.Parse(config.Url)
// if err != nil {
// return nil, err
// }
// rel, err := baseUrl.Parse(location)
// param := map[string]string{}
// param["username"] = "admin"
// param["password"] = "argocd-server-6cd5bcffd4-j6kcx"
// paramJson, err := json.Marshal(param)
// if err != nil {
// return nil, err
// }
// req, _ := http.NewRequest("POST", rel.String(), bytes.NewBuffer(paramJson))
// transCfg := &http.Transport{
// TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify},
// }
// cookieJar, err := cookiejar.New(nil)
// if err != nil {
// return nil, err
// }
// client := &http.Client{Transport: transCfg, Jar: cookieJar, Timeout: time.Duration(config.Timeout)}
// res, err := client.Do(req)
// defer res.Body.Close()
// if res.StatusCode != http.StatusOK {
// return nil, err
// }*/
// return &ArgoSession{}, nil
//}
50 changes: 40 additions & 10 deletions internal/util/ArgoUtil/ClusterService.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,49 @@ import (
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
)

type ClusterService interface {
type ClusterConfig struct {
BearerToken string `json:"bearerToken"`
TLSClientConfig `json:"tlsClientConfig"`
}
type TLSClientConfig struct {
Insecure bool `json:"insecure"`
}
type ClusterRequest struct {
Name string `json:"name"`
Server string `json:"server"`
Config ClusterConfig `json:"config"`
}
type ClusterResponse struct {
Id string `json:"id"`
Server string `json:"server"`
Name string `json:"name"`
ServerVersion string `json:"serverVersion"`
Config ClusterConfig `json:"config"`
}

type ArgoClusterService interface {
GetClusterByServer(server string) (*v1alpha1.Cluster, error)
ClusterList() (*v1alpha1.ClusterList, error)
CreateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error)
CreateClusterWithGitOps(request *ClusterRequest, acdToken string) (*ClusterRequest, error)
UpdateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error)
DeleteCluster(server string) (string, error)
}

type ClusterServiceImpl struct {
type ArgoClusterServiceImpl struct {
*ArgoSession
id int
location string
}

func NewClusterServiceImpl(session *ArgoSession) *ClusterServiceImpl {
return &ClusterServiceImpl{
func NewArgoClusterServiceImpl(session *ArgoSession) *ArgoClusterServiceImpl {
return &ArgoClusterServiceImpl{
ArgoSession: session,
location: "/api/v1/clusters",
location: "/api/v1/clusters?upsert=true",
}
}

func (impl *ClusterServiceImpl) GetClusterByServer(server string) (*v1alpha1.Cluster, error) {
func (impl *ArgoClusterServiceImpl) GetClusterByServer(server string) (*v1alpha1.Cluster, error) {

path := impl.location + "/" + server
res := &v1alpha1.Cluster{}
Expand All @@ -53,7 +74,7 @@ func (impl *ClusterServiceImpl) GetClusterByServer(server string) (*v1alpha1.Clu
return res, nil
}

func (impl *ClusterServiceImpl) ClusterList() (*v1alpha1.ClusterList, error) {
func (impl *ArgoClusterServiceImpl) ClusterList() (*v1alpha1.ClusterList, error) {

path := impl.location
res := &v1alpha1.ClusterList{}
Expand All @@ -64,7 +85,7 @@ func (impl *ClusterServiceImpl) ClusterList() (*v1alpha1.ClusterList, error) {
return res, nil
}

func (impl *ClusterServiceImpl) CreateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error) {
func (impl *ArgoClusterServiceImpl) CreateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error) {

path := impl.location
res := &v1alpha1.Cluster{}
Expand All @@ -75,8 +96,17 @@ func (impl *ClusterServiceImpl) CreateCluster(cluster v1alpha1.Cluster) (*v1alph
}
return res, nil
}
func (impl *ArgoClusterServiceImpl) CreateClusterWithGitOps(request *ClusterRequest, acdToken string) (*ClusterRequest, error) {
path := impl.location
res := &ClusterRequest{}
_, _, err := impl.DoRequestForArgo(&ClientRequest{ResponseBody: res, Path: path, RequestBody: request, Method: "POST"}, acdToken)
if err != nil {
return nil, err
}
return res, nil
}

func (impl *ClusterServiceImpl) UpdateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error) {
func (impl *ArgoClusterServiceImpl) UpdateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error) {

path := impl.location + "/" + cluster.Server
res := &v1alpha1.Cluster{}
Expand All @@ -87,7 +117,7 @@ func (impl *ClusterServiceImpl) UpdateCluster(cluster v1alpha1.Cluster) (*v1alph
return res, nil
}

func (impl *ClusterServiceImpl) DeleteCluster(server string) (string, error) {
func (impl *ArgoClusterServiceImpl) DeleteCluster(server string) (string, error) {
res := ""
path := impl.location + "/" + server
_, _, err := impl.DoRequest(&ClientRequest{ResponseBody: &res, Path: path, Method: "DELETE"})
Expand Down
20 changes: 18 additions & 2 deletions internal/util/ArgoUtil/RepositoryService.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,17 @@

package ArgoUtil

import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
import (
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
)

type Repository struct {
Repo string `json:"repo"`
}

type RepositoryService interface {
Create(repositoryRequest *v1alpha1.Repository) (repository *v1alpha1.Repository, err error)
CreateRepository(repositoryRequest *Repository, acdToken string) (repository *Repository, err error)
}

type RepositoryServiceImpl struct {
Expand All @@ -31,7 +38,7 @@ type RepositoryServiceImpl struct {
func NewRepositoryService(session *ArgoSession) *RepositoryServiceImpl {
return &RepositoryServiceImpl{
ArgoSession: session,
location: "/api/v1/repositories",
location: "/api/v1/repositories?upsert=true",
}
}

Expand All @@ -43,3 +50,12 @@ func (impl RepositoryServiceImpl) Create(repositoryRequest *v1alpha1.Repository)
}
return res, nil
}
func (impl RepositoryServiceImpl) CreateRepository(repositoryRequest *Repository, acdToken string) (repository *Repository, err error) {
res := &Repository{}
_, _, err = impl.DoRequestForArgo(&ClientRequest{ResponseBody: res, Path: impl.location, Method: "POST", RequestBody: repositoryRequest}, acdToken)
if err != nil {
return nil, err
}
impl.logger.Errorw("failed to register on Argo", "err", err)
return res, nil
}
Loading