Added curd operation and private hub support in myhub

Signed-off-by: Amit Kumar Das <amitkumar.das@mayadata.io>
This commit is contained in:
Amit Kumar Das 2021-01-11 18:31:37 +05:30
parent c5723964aa
commit b9cf1bad41
12 changed files with 2695 additions and 707 deletions

View File

@ -19,7 +19,7 @@ require (
github.com/tidwall/sjson v1.1.1
github.com/vektah/gqlparser/v2 v2.0.1
go.mongodb.org/mongo-driver v1.3.5
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect

File diff suppressed because it is too large Load Diff

View File

@ -58,10 +58,16 @@ type Charts struct {
}
type CloningInput struct {
HubName string `json:"HubName"`
ProjectID string `json:"ProjectID"`
RepoBranch string `json:"RepoBranch"`
RepoURL string `json:"RepoURL"`
HubName string `json:"HubName"`
ProjectID string `json:"ProjectID"`
RepoBranch string `json:"RepoBranch"`
RepoURL string `json:"RepoURL"`
IsPrivate bool `json:"IsPrivate"`
AuthType AuthType `json:"AuthType"`
Token *string `json:"Token"`
UserName *string `json:"UserName"`
Password *string `json:"Password"`
SSHPrivateKey *string `json:"SSHPrivateKey"`
}
type Cluster struct {
@ -137,9 +143,16 @@ type ClusterInput struct {
}
type CreateMyHub struct {
HubName string `json:"HubName"`
RepoURL string `json:"RepoURL"`
RepoBranch string `json:"RepoBranch"`
HubName string `json:"HubName"`
RepoURL string `json:"RepoURL"`
RepoBranch string `json:"RepoBranch"`
IsPrivate bool `json:"IsPrivate"`
AuthType AuthType `json:"AuthType"`
Token *string `json:"Token"`
UserName *string `json:"UserName"`
Password *string `json:"Password"`
SSHPrivateKey *string `json:"SSHPrivateKey"`
SSHPublicKey *string `json:"SSHPublicKey"`
}
type CreateUserInput struct {
@ -197,22 +210,39 @@ type Metadata struct {
}
type MyHub struct {
ID string `json:"id"`
RepoURL string `json:"RepoURL"`
RepoBranch string `json:"RepoBranch"`
ProjectID string `json:"ProjectID"`
HubName string `json:"HubName"`
CreatedAt string `json:"CreatedAt"`
UpdatedAt string `json:"UpdatedAt"`
ID string `json:"id"`
RepoURL string `json:"RepoURL"`
RepoBranch string `json:"RepoBranch"`
ProjectID string `json:"ProjectID"`
HubName string `json:"HubName"`
IsPrivate bool `json:"IsPrivate"`
AuthType AuthType `json:"AuthType"`
Token *string `json:"Token"`
UserName *string `json:"UserName"`
Password *string `json:"Password"`
SSHPrivateKey *string `json:"SSHPrivateKey"`
IsRemoved bool `json:"IsRemoved"`
CreatedAt string `json:"CreatedAt"`
UpdatedAt string `json:"UpdatedAt"`
LastSyncedAt string `json:"LastSyncedAt"`
}
type MyHubStatus struct {
ID string `json:"id"`
RepoURL string `json:"RepoURL"`
RepoBranch string `json:"RepoBranch"`
IsAvailable bool `json:"IsAvailable"`
TotalExp string `json:"TotalExp"`
HubName string `json:"HubName"`
ID string `json:"id"`
RepoURL string `json:"RepoURL"`
RepoBranch string `json:"RepoBranch"`
IsAvailable bool `json:"IsAvailable"`
TotalExp string `json:"TotalExp"`
HubName string `json:"HubName"`
IsPrivate bool `json:"IsPrivate"`
AuthType AuthType `json:"AuthType"`
Token *string `json:"Token"`
UserName *string `json:"UserName"`
Password *string `json:"Password"`
IsRemoved bool `json:"IsRemoved"`
SSHPrivateKey *string `json:"SSHPrivateKey"`
SSHPublicKey *string `json:"SSHPublicKey"`
LastSyncedAt string `json:"LastSyncedAt"`
}
type PackageInformation struct {
@ -261,6 +291,11 @@ type Provider struct {
Name string `json:"Name"`
}
type SSHKey struct {
PublicKey string `json:"publicKey"`
PrivateKey string `json:"privateKey"`
}
type ScheduledWorkflows struct {
WorkflowID string `json:"workflow_id"`
WorkflowManifest string `json:"workflow_manifest"`
@ -293,6 +328,20 @@ type Spec struct {
ChaosType *string `json:"ChaosType"`
}
type UpdateMyHub struct {
ID string `json:"id"`
HubName string `json:"HubName"`
RepoURL string `json:"RepoURL"`
RepoBranch string `json:"RepoBranch"`
IsPrivate bool `json:"IsPrivate"`
AuthType AuthType `json:"AuthType"`
Token *string `json:"Token"`
UserName *string `json:"UserName"`
Password *string `json:"Password"`
SSHPrivateKey *string `json:"SSHPrivateKey"`
SSHPublicKey *string `json:"SSHPublicKey"`
}
type UpdateUserInput struct {
ID string `json:"id"`
Name *string `json:"name"`
@ -376,6 +425,49 @@ type Weightages struct {
Weightage int `json:"weightage"`
}
type AuthType string
const (
AuthTypeBasic AuthType = "basic"
AuthTypeToken AuthType = "token"
AuthTypeSSH AuthType = "ssh"
)
var AllAuthType = []AuthType{
AuthTypeBasic,
AuthTypeToken,
AuthTypeSSH,
}
func (e AuthType) IsValid() bool {
switch e {
case AuthTypeBasic, AuthTypeToken, AuthTypeSSH:
return true
}
return false
}
func (e AuthType) String() string {
return string(e)
}
func (e *AuthType) UnmarshalGQL(v interface{}) error {
str, ok := v.(string)
if !ok {
return fmt.Errorf("enums must be strings")
}
*e = AuthType(str)
if !e.IsValid() {
return fmt.Errorf("%s is not a valid AuthType", str)
}
return nil
}
func (e AuthType) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(e.String()))
}
type MemberRole string
const (

View File

@ -1,107 +1,173 @@
enum AuthType {
basic
token
ssh
}
type MyHub {
id: ID!
RepoURL: String!
RepoBranch: String!
ProjectID: String!
HubName: String!
CreatedAt: String!
UpdatedAt: String!
id: ID!
RepoURL: String!
RepoBranch: String!
ProjectID: String!
HubName: String!
IsPrivate: Boolean!
# Auth Types-
# token: Token based authentication
# basic: Username/Password based authentication
# ssh: SSH based authentication
AuthType: AuthType!
Token: String
UserName: String
Password: String
SSHPrivateKey: String
IsRemoved: Boolean!
CreatedAt: String!
UpdatedAt: String!
LastSyncedAt: String!
}
type Charts {
Charts: [Chart!]!
Charts: [Chart!]!
}
type Chart {
ApiVersion: String!
Kind: String!
Metadata: Metadata!
Spec: Spec!
PackageInfo: PackageInformation!
Experiments: [Chart!]!
ApiVersion: String!
Kind: String!
Metadata: Metadata!
Spec: Spec!
PackageInfo: PackageInformation!
Experiments: [Chart!]!
}
type Maintainer {
Name: String!
Email: String!
Name: String!
Email: String!
}
type Link {
Name: String!
Url: String!
Name: String!
Url: String!
}
type Metadata {
Name: String!
Version: String!
Annotations: Annotation!
Name: String!
Version: String!
Annotations: Annotation!
}
type Annotation {
Categories: String!
Vendor: String!
CreatedAt: String!
Repository: String!
Support: String!
ChartDescription: String!
Categories: String!
Vendor: String!
CreatedAt: String!
Repository: String!
Support: String!
ChartDescription: String!
}
type Spec {
DisplayName: String!
CategoryDescription: String!
Keywords: [String!]!
Maturity: String!
Maintainers: [Maintainer!]!
MinKubeVersion: String!
Provider: String!
Links: [Link!]!
Experiments: [String!]!
ChaosExpCRDLink: String!
Platforms: [String!]!
ChaosType: String
DisplayName: String!
CategoryDescription: String!
Keywords: [String!]!
Maturity: String!
Maintainers: [Maintainer!]!
MinKubeVersion: String!
Provider: String!
Links: [Link!]!
Experiments: [String!]!
ChaosExpCRDLink: String!
Platforms: [String!]!
ChaosType: String
}
type Provider {
Name: String!
Name: String!
}
type PackageInformation {
PackageName: String!
Experiments: [Experiments!]!
PackageName: String!
Experiments: [Experiments!]!
}
type Experiments {
Name: String!
CSV: String!
Desc: String!
Name: String!
CSV: String!
Desc: String!
}
type MyHubStatus {
id: ID!
RepoURL: String!
RepoBranch: String!
IsAvailable: Boolean!
TotalExp: String!
HubName: String!
id: ID!
RepoURL: String!
RepoBranch: String!
IsAvailable: Boolean!
TotalExp: String!
HubName: String!
IsPrivate: Boolean!
# Auth Types-
# token: Token based authentication
# basic: Username/Password based authentication
# ssh: SSH based authentication
AuthType: AuthType!
Token: String
UserName: String
Password: String
IsRemoved: Boolean!
SSHPrivateKey: String
SSHPublicKey: String
LastSyncedAt: String!
}
input CreateMyHub {
HubName: String!
RepoURL: String!
RepoBranch: String!
HubName: String!
RepoURL: String!
RepoBranch: String!
IsPrivate: Boolean!
# Auth Types-
# token: Token based authentication
# basic: Username/Password based authentication
# ssh: SSH based authentication
AuthType: AuthType!
Token: String
UserName: String
Password: String
SSHPrivateKey: String
SSHPublicKey: String
}
input ExperimentInput {
ProjectID: String!
ChartName: String!
ExperimentName: String!
HubName: String!
FileType: String
ProjectID: String!
ChartName: String!
ExperimentName: String!
HubName: String!
FileType: String
}
input CloningInput {
HubName: String!
ProjectID: String!
RepoBranch: String!
RepoURL: String!
HubName: String!
ProjectID: String!
RepoBranch: String!
RepoURL: String!
IsPrivate: Boolean!
# Auth Types-
# token: Token based authentication
# basic: Username/Password based authentication
# ssh: SSH based authentication
AuthType: AuthType!
Token: String
UserName: String
Password: String
SSHPrivateKey: String
}
input UpdateMyHub {
id: String!
HubName: String!
RepoURL: String!
RepoBranch: String!
IsPrivate: Boolean!
AuthType: AuthType!
Token: String
UserName: String
Password: String
SSHPrivateKey: String
SSHPublicKey: String
}

View File

@ -5,285 +5,298 @@
directive @authorized on FIELD_DEFINITION
type Cluster {
cluster_id: ID!
project_id: ID!
cluster_name: String!
description: String
platform_name: String!
access_key: String!
is_registered: Boolean!
is_cluster_confirmed: Boolean!
is_active: Boolean!
updated_at: String!
created_at: String!
cluster_type: String!
no_of_schedules: Int
no_of_workflows: Int
token: String!
agent_namespace: String
serviceaccount: String
agent_scope: String!
agent_ns_exists: Boolean
agent_sa_exists: Boolean
cluster_id: ID!
project_id: ID!
cluster_name: String!
description: String
platform_name: String!
access_key: String!
is_registered: Boolean!
is_cluster_confirmed: Boolean!
is_active: Boolean!
updated_at: String!
created_at: String!
cluster_type: String!
no_of_schedules: Int
no_of_workflows: Int
token: String!
agent_namespace: String
serviceaccount: String
agent_scope: String!
agent_ns_exists: Boolean
agent_sa_exists: Boolean
}
input ClusterInput {
cluster_name: String!
description: String
platform_name: String!
project_id: ID!
cluster_type: String!
agent_namespace: String
serviceaccount: String
agent_scope: String!
agent_ns_exists: Boolean
agent_sa_exists: Boolean
cluster_name: String!
description: String
platform_name: String!
project_id: ID!
cluster_type: String!
agent_namespace: String
serviceaccount: String
agent_scope: String!
agent_ns_exists: Boolean
agent_sa_exists: Boolean
}
type ClusterEvent {
event_id: ID!
event_type: String!
event_name: String!
description: String!
cluster: Cluster!
event_id: ID!
event_type: String!
event_name: String!
description: String!
cluster: Cluster!
}
type ActionPayload {
request_type: String!
k8s_manifest: String!
namespace: String!
external_data: String
request_type: String!
k8s_manifest: String!
namespace: String!
external_data: String
}
type ClusterAction {
project_id: ID!
action: ActionPayload!
project_id: ID!
action: ActionPayload!
}
input ClusterActionInput {
cluster_id: ID!
action: String!
cluster_id: ID!
action: String!
}
input ClusterEventInput {
event_name: String!
description: String!
cluster_id: String!
access_key: String!
event_name: String!
description: String!
cluster_id: String!
access_key: String!
}
input ClusterIdentity {
cluster_id: String!
access_key: String!
cluster_id: String!
access_key: String!
}
type ClusterConfirmResponse {
isClusterConfirmed: Boolean!
newClusterKey: String
cluster_id: String
isClusterConfirmed: Boolean!
newClusterKey: String
cluster_id: String
}
input WeightagesInput {
experiment_name: String!
weightage: Int!
experiment_name: String!
weightage: Int!
}
type weightages {
experiment_name: String!
weightage: Int!
experiment_name: String!
weightage: Int!
}
input ChaosWorkFlowInput {
workflow_id: String
workflow_manifest: String!
cronSyntax: String!
workflow_name: String!
workflow_description: String!
weightages: [WeightagesInput!]!
isCustomWorkflow: Boolean!
project_id: ID!
cluster_id: ID!
workflow_id: String
workflow_manifest: String!
cronSyntax: String!
workflow_name: String!
workflow_description: String!
weightages: [WeightagesInput!]!
isCustomWorkflow: Boolean!
project_id: ID!
cluster_id: ID!
}
type ChaosWorkFlowResponse {
workflow_id: String!
cronSyntax: String!
workflow_name: String!
workflow_description: String!
isCustomWorkflow: Boolean!
workflow_id: String!
cronSyntax: String!
workflow_name: String!
workflow_description: String!
isCustomWorkflow: Boolean!
}
type WorkflowRun {
workflow_run_id: ID!
workflow_id: ID!
cluster_name: String!
last_updated: String!
project_id: ID!
cluster_id: ID!
workflow_name: String!
cluster_type: String
execution_data: String!
workflow_run_id: ID!
workflow_id: ID!
cluster_name: String!
last_updated: String!
project_id: ID!
cluster_id: ID!
workflow_name: String!
cluster_type: String
execution_data: String!
}
input WorkflowRunInput {
workflow_id: ID!
workflow_run_id: ID!
workflow_name: String!
execution_data: String!
cluster_id: ClusterIdentity!
completed: Boolean!
workflow_id: ID!
workflow_run_id: ID!
workflow_name: String!
execution_data: String!
cluster_id: ClusterIdentity!
completed: Boolean!
}
type PodLogResponse {
workflow_run_id: ID!
pod_name: String!
pod_type: String!
log: String!
workflow_run_id: ID!
pod_name: String!
pod_type: String!
log: String!
}
input PodLog {
cluster_id: ClusterIdentity!
request_id: ID!
workflow_run_id: ID!
pod_name: String!
pod_type: String!
log: String!
cluster_id: ClusterIdentity!
request_id: ID!
workflow_run_id: ID!
pod_name: String!
pod_type: String!
log: String!
}
input PodLogRequest {
cluster_id: ID!
workflow_run_id: ID!
pod_name: String!
pod_namespace: String!
pod_type: String!
exp_pod: String
runner_pod: String
chaos_namespace: String
cluster_id: ID!
workflow_run_id: ID!
pod_name: String!
pod_namespace: String!
pod_type: String!
exp_pod: String
runner_pod: String
chaos_namespace: String
}
type ScheduledWorkflows {
workflow_id: String!
workflow_manifest: String!
cronSyntax: String!
cluster_name: String!
workflow_name: String!
workflow_description: String!
weightages: [weightages!]!
isCustomWorkflow: Boolean!
updated_at: String!
created_at: String!
project_id: ID!
cluster_id: ID!
cluster_type: String!
isRemoved: Boolean!
workflow_id: String!
workflow_manifest: String!
cronSyntax: String!
cluster_name: String!
workflow_name: String!
workflow_description: String!
weightages: [weightages!]!
isCustomWorkflow: Boolean!
updated_at: String!
created_at: String!
project_id: ID!
cluster_id: ID!
cluster_type: String!
isRemoved: Boolean!
}
type Workflow {
workflow_id: String!
workflow_manifest: String!
cronSyntax: String!
cluster_name: String!
workflow_name: String!
workflow_description: String!
weightages: [weightages!]!
isCustomWorkflow: Boolean!
updated_at: String!
created_at: String!
project_id: ID!
cluster_id: ID!
cluster_type: String!
isRemoved: Boolean!
workflow_runs: [WorkflowRuns]
workflow_id: String!
workflow_manifest: String!
cronSyntax: String!
cluster_name: String!
workflow_name: String!
workflow_description: String!
weightages: [weightages!]!
isCustomWorkflow: Boolean!
updated_at: String!
created_at: String!
project_id: ID!
cluster_id: ID!
cluster_type: String!
isRemoved: Boolean!
workflow_runs: [WorkflowRuns]
}
type WorkflowRuns {
execution_data: String!
workflow_run_id: ID!
last_updated: String!
execution_data: String!
workflow_run_id: ID!
last_updated: String!
}
type clusterRegResponse {
token: String!
cluster_id: String!
cluster_name: String!
token: String!
cluster_id: String!
cluster_name: String!
}
type SSHKey {
publicKey: String!
privateKey: String!
}
type Query {
# [Deprecated soon]
getWorkFlowRuns(project_id: String!): [WorkflowRun!]! @authorized
# [Deprecated soon]
getWorkFlowRuns(project_id: String!): [WorkflowRun!]! @authorized
getCluster(project_id: String!, cluster_type: String): [Cluster!]! @authorized
getCluster(project_id: String!, cluster_type: String): [Cluster!]! @authorized
getUser(username: String!): User! @authorized
getUser(username: String!): User! @authorized
getProject(projectID: String!): Project! @authorized
getProject(projectID: String!): Project! @authorized
users: [User!]! @authorized
users: [User!]! @authorized
# [Deprecated soon]
getScheduledWorkflows(project_id: String!): [ScheduledWorkflows]! @authorized
# [Deprecated soon]
getScheduledWorkflows(project_id: String!): [ScheduledWorkflows]! @authorized
ListWorkflow(project_id: String!, workflow_ids: [ID]): [Workflow]! @authorized
ListWorkflow(project_id: String!, workflow_ids: [ID]): [Workflow]! @authorized
getCharts(HubName: String!, projectID: String!): [Chart!]! @authorized
getCharts(HubName: String!, projectID: String!): [Chart!]! @authorized
getHubExperiment(experimentInput: ExperimentInput!): Chart! @authorized
getHubExperiment(experimentInput: ExperimentInput!): Chart! @authorized
getHubStatus(projectID: String!): [MyHubStatus]! @authorized
getHubStatus(projectID: String!): [MyHubStatus]! @authorized
getYAMLData(experimentInput: ExperimentInput!): String!
getYAMLData(experimentInput: ExperimentInput!): String!
}
type Mutation {
#It is used to create external cluster.
userClusterReg(clusterInput: ClusterInput!): clusterRegResponse! @authorized
#It is used to create external cluster.
userClusterReg(clusterInput: ClusterInput!): clusterRegResponse! @authorized
#It is used to create chaosworkflow
createChaosWorkFlow(input: ChaosWorkFlowInput!): ChaosWorkFlowResponse!
@authorized
#It is used to create chaosworkflow
createChaosWorkFlow(input: ChaosWorkFlowInput!): ChaosWorkFlowResponse!
@authorized
createUser(user: CreateUserInput!): User! @authorized
createUser(user: CreateUserInput!): User! @authorized
updateUser(user: UpdateUserInput!): String! @authorized
updateUser(user: UpdateUserInput!): String! @authorized
deleteChaosWorkflow(workflowid: String!): Boolean! @authorized
deleteChaosWorkflow(workflowid: String!): Boolean! @authorized
sendInvitation(member: MemberInput!): Member @authorized
sendInvitation(member: MemberInput!): Member @authorized
acceptInvitation(member: MemberInput!): String! @authorized
acceptInvitation(member: MemberInput!): String! @authorized
declineInvitation(member: MemberInput!): String! @authorized
declineInvitation(member: MemberInput!): String! @authorized
removeInvitation(member: MemberInput!): String! @authorized
removeInvitation(member: MemberInput!): String! @authorized
#It is used to confirm the subscriber registration
clusterConfirm(identity: ClusterIdentity!): ClusterConfirmResponse!
#It is used to confirm the subscriber registration
clusterConfirm(identity: ClusterIdentity!): ClusterConfirmResponse!
#It is used to send cluster related events from the subscriber
newClusterEvent(clusterEvent: ClusterEventInput!): String!
#It is used to send cluster related events from the subscriber
newClusterEvent(clusterEvent: ClusterEventInput!): String!
chaosWorkflowRun(workflowData: WorkflowRunInput!): String!
chaosWorkflowRun(workflowData: WorkflowRunInput!): String!
podLog(log: PodLog!): String!
podLog(log: PodLog!): String!
addMyHub(myhubInput: CreateMyHub!, projectID: String!): MyHub! @authorized
addMyHub(myhubInput: CreateMyHub!, projectID: String!): MyHub! @authorized
syncHub(projectID: String!, HubName: String!): [MyHubStatus!]! @authorized
saveMyHub(myhubInput: CreateMyHub!, projectID: String!): MyHub! @authorized
updateChaosWorkflow(input: ChaosWorkFlowInput): ChaosWorkFlowResponse!
@authorized
syncHub(id: ID!): [MyHubStatus!]! @authorized
deleteClusterReg(cluster_id: String!): String! @authorized
updateChaosWorkflow(input: ChaosWorkFlowInput): ChaosWorkFlowResponse!
@authorized
deleteClusterReg(cluster_id: String!): String! @authorized
generaterSSHKey: SSHKey! @authorized
updateMyHub(myhubInput: UpdateMyHub!, projectID: String!): MyHub! @authorized
deleteMyHub(hub_id: String!): Boolean! @authorized
}
type Subscription {
#It is used to listen cluster events from the graphql server
clusterEventListener(project_id: String!): ClusterEvent! @authorized
#It is used to listen cluster events from the graphql server
clusterEventListener(project_id: String!): ClusterEvent! @authorized
workflowEventListener(project_id: String!): WorkflowRun! @authorized
workflowEventListener(project_id: String!): WorkflowRun! @authorized
getPodLog(podDetails: PodLogRequest!): PodLogResponse! @authorized
getPodLog(podDetails: PodLogRequest!): PodLogResponse! @authorized
#It is used to listen cluster operation request from the graphql server
clusterConnect(clusterInfo: ClusterIdentity!): ClusterAction!
#It is used to listen cluster operation request from the graphql server
clusterConnect(clusterInfo: ClusterIdentity!): ClusterAction!
}

View File

@ -6,6 +6,7 @@ package graph
import (
"context"
"errors"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/myhub/gitops"
"log"
"strconv"
"time"
@ -81,8 +82,12 @@ func (r *mutationResolver) AddMyHub(ctx context.Context, myhubInput model.Create
return myhub.AddMyHub(ctx, myhubInput, projectID)
}
func (r *mutationResolver) SyncHub(ctx context.Context, projectID string, hubName string) ([]*model.MyHubStatus, error) {
return myhub.SyncHub(ctx, projectID, hubName)
func (r *mutationResolver) SaveMyHub(ctx context.Context, myhubInput model.CreateMyHub, projectID string) (*model.MyHub, error) {
return myhub.SaveMyHub(ctx, myhubInput, projectID)
}
func (r *mutationResolver) SyncHub(ctx context.Context, id string) ([]*model.MyHubStatus, error) {
return myhub.SyncHub(ctx, id)
}
func (r *mutationResolver) UpdateChaosWorkflow(ctx context.Context, input *model.ChaosWorkFlowInput) (*model.ChaosWorkFlowResponse, error) {
@ -93,6 +98,26 @@ func (r *mutationResolver) DeleteClusterReg(ctx context.Context, clusterID strin
return mutations.DeleteCluster(clusterID, *store)
}
func (r *mutationResolver) GeneraterSSHKey(ctx context.Context) (*model.SSHKey, error) {
publicKey, privateKey, err := gitops.GenerateKeys()
if err != nil {
return nil, err
}
return &model.SSHKey{
PrivateKey: privateKey,
PublicKey: publicKey,
}, nil
}
func (r *mutationResolver) UpdateMyHub(ctx context.Context, myhubInput model.UpdateMyHub, projectID string) (*model.MyHub, error) {
return myhub.UpdateMyHub(ctx, myhubInput, projectID)
}
func (r *mutationResolver) DeleteMyHub(ctx context.Context, hubID string) (bool, error) {
return myhub.DeleteMyHub(ctx, hubID)
}
func (r *queryResolver) GetWorkFlowRuns(ctx context.Context, projectID string) ([]*model.WorkflowRun, error) {
return queries.QueryWorkflowRuns(projectID)
}

View File

@ -2,6 +2,7 @@ package operations
import (
"context"
"errors"
"log"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb"
@ -60,3 +61,27 @@ func GetHubs(ctx context.Context) ([]dbSchema.MyHub, error) {
}
return MyHubs, nil
}
//GetHubByID
func GetHubByID(ctx context.Context, hubID string) (dbSchema.MyHub, error) {
var myHub dbSchema.MyHub
err := myhubCollection.FindOne(ctx, bson.M{"myhub_id": hubID}).Decode(&myHub)
if err != nil {
return dbSchema.MyHub{}, err
}
return myHub, nil
}
func UpdateMyHub(ctx context.Context, query bson.D, update bson.D) error {
updateResult, err := myhubCollection.UpdateOne(ctx, query, update)
if err != nil {
return err
}
if updateResult.MatchedCount == 0 {
return errors.New("Myhub collection query didn't matched")
}
return nil
}

View File

@ -4,25 +4,42 @@ import "github.com/litmuschaos/litmus/litmus-portal/graphql-server/graph/model"
//MyHub ...
type MyHub struct {
ID string `bson:"myhub_id"`
ProjectID string `bson:"project_id"`
RepoURL string `bson:"repo_url"`
RepoBranch string `bson:"repo_branch"`
HubName string `bson:"hub_name"`
CreatedAt string `bson:"created_at"`
UpdatedAt string `bson:"updated_at"`
ID string `bson:"myhub_id"`
ProjectID string `bson:"project_id"`
RepoURL string `bson:"repo_url"`
RepoBranch string `bson:"repo_branch"`
HubName string `bson:"hub_name"`
IsPrivate bool `bson:"IsPrivate"`
AuthType string `bson:"AuthType"`
Token *string `bson:"Token"`
UserName *string `bson:"UserName"`
Password *string `bson:"Password"`
SSHPrivateKey *string `bson:"SSHPrivateKey"`
SSHPublicKey *string `bson:"SSHPublicKey"`
IsRemoved bool `bson:"IsRemoved"`
CreatedAt string `bson:"created_at"`
UpdatedAt string `bson:"updated_at"`
LastSyncedAt string `bson:"last_synced_at"`
}
//GetOutputMyHub ...
func (myhub *MyHub) GetOutputMyHub() *model.MyHub {
return &model.MyHub{
ID: myhub.ID,
ProjectID: myhub.ProjectID,
RepoURL: myhub.RepoURL,
RepoBranch: myhub.RepoBranch,
HubName: myhub.HubName,
CreatedAt: myhub.CreatedAt,
UpdatedAt: myhub.UpdatedAt,
ID: myhub.ID,
ProjectID: myhub.ProjectID,
RepoURL: myhub.RepoURL,
RepoBranch: myhub.RepoBranch,
HubName: myhub.HubName,
IsPrivate: myhub.IsPrivate,
UserName: myhub.UserName,
Password: myhub.Password,
AuthType: model.AuthType(myhub.AuthType),
Token: myhub.Token,
IsRemoved: myhub.IsRemoved,
SSHPrivateKey: myhub.SSHPrivateKey,
CreatedAt: myhub.CreatedAt,
UpdatedAt: myhub.UpdatedAt,
LastSyncedAt: myhub.LastSyncedAt,
}
}

View File

@ -2,6 +2,10 @@ package gitops
import (
"fmt"
ssh2 "golang.org/x/crypto/ssh"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
"gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
"os"
"strings"
@ -11,8 +15,8 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing"
)
//GitConfig ...
type GitConfig struct {
//MyHubConfig ...
type MyHubConfig struct {
ProjectID string
RepositoryURL string
RemoteName string
@ -20,34 +24,38 @@ type GitConfig struct {
RemoteCommit string
HubName string
Branch string
IsPrivate bool
UserName *string
Password *string
AuthType model.AuthType
Token *string
SSHPrivateKey *string
}
var (
repository *git.Repository
workTree *git.Worktree
plumbingRef *plumbing.Reference
status *git.Status
err error
)
const (
defaultPath = "/tmp/version/"
)
//GetClonePath is used to construct path for Repository.
func GetClonePath(c GitConfig) string {
func GetClonePath(c MyHubConfig) string {
RepoPath := defaultPath + c.ProjectID + "/" + c.HubName
return RepoPath
}
//GitConfigConstruct is used for constructing the gitconfig
func GitConfigConstruct(repoData model.CloningInput) GitConfig {
gitConfig := GitConfig{
func GitConfigConstruct(repoData model.CloningInput) MyHubConfig {
gitConfig := MyHubConfig{
ProjectID: repoData.ProjectID,
HubName: repoData.HubName,
RepositoryURL: repoData.RepoURL,
RemoteName: "origin",
Branch: repoData.RepoBranch,
IsPrivate: repoData.IsPrivate,
UserName: repoData.UserName,
Password: repoData.Password,
AuthType: repoData.AuthType,
Token: repoData.Token,
SSHPrivateKey: repoData.SSHPrivateKey,
}
return gitConfig
@ -56,18 +64,56 @@ func GitConfigConstruct(repoData model.CloningInput) GitConfig {
//GitClone Trigger is reponsible for setting off the go routine for git-op
func GitClone(repoData model.CloningInput) error {
gitConfig := GitConfigConstruct(repoData)
_, err := gitConfig.getChaosChartRepo()
if err != nil {
fmt.Print("Error in cloning")
return err
if repoData.IsPrivate {
_, err := gitConfig.getPrivateChaosChartRepo()
if err != nil {
fmt.Print("Error in cloning")
return err
}
} else {
_, err := gitConfig.getChaosChartRepo()
if err != nil {
fmt.Print("Error in cloning")
return err
}
}
//Successfully Cloned
return nil
}
//getChaosChartVersion is responsible for plain cloning the repository
func (c MyHubConfig) getChaosChartRepo() (string, error) {
ClonePath := GetClonePath(c)
os.RemoveAll(ClonePath)
_, err := git.PlainClone(ClonePath, false, &git.CloneOptions{
URL: c.RepositoryURL, Progress: os.Stdout,
ReferenceName: plumbing.NewBranchReferenceName(c.Branch),
})
return c.Branch, err
}
//getPrivateChaosChartVersion is responsible for plain cloning the private repository
func (c MyHubConfig) getPrivateChaosChartRepo() (string, error) {
ClonePath := GetClonePath(c)
os.RemoveAll(ClonePath)
auth, err := c.generateAuthMethod()
if err != nil {
return "", err
}
_, err = git.PlainClone(ClonePath, false, &git.CloneOptions{
Auth: auth,
URL: c.RepositoryURL,
Progress: os.Stdout,
ReferenceName: plumbing.NewBranchReferenceName(c.Branch),
})
return c.Branch, err
}
//GitSyncHandlerForProjects ...
func GitSyncHandlerForProjects(repoData model.CloningInput) error {
gitConfig := GitConfigConstruct(repoData)
if err := gitConfig.chaosChartSyncHandler(); err != nil {
log.Error(err)
@ -78,32 +124,33 @@ func GitSyncHandlerForProjects(repoData model.CloningInput) error {
return nil
}
//getChaosChartVersion is responsible for plain cloning the repository
func (c GitConfig) getChaosChartRepo() (string, error) {
ClonePath := GetClonePath(c)
os.RemoveAll(ClonePath)
_, err := git.PlainClone(ClonePath, false, &git.CloneOptions{
URL: c.RepositoryURL, Progress: os.Stdout,
ReferenceName: plumbing.NewBranchReferenceName(c.Branch),
})
return c.Branch, err
}
// chaosChartSyncHandler is responsible for all the handler functions
func (c GitConfig) chaosChartSyncHandler() error {
func (c MyHubConfig) chaosChartSyncHandler() error {
repositoryExists, err := c.isRepositoryExists()
if err != nil {
return fmt.Errorf("Error while checking repo exists, err: %s", err)
}
log.WithFields(log.Fields{"repositoryExists": repositoryExists}).Info("Executed isRepositoryExists()... ")
if !repositoryExists {
return c.HandlerForNonExistingRepository()
return GitClone(model.CloningInput{
HubName: c.HubName,
ProjectID: c.ProjectID,
RepoURL: c.RepositoryURL,
RepoBranch: c.Branch,
IsPrivate: c.IsPrivate,
AuthType: c.AuthType,
Token: c.Token,
UserName: c.UserName,
Password: c.Password,
SSHPrivateKey: c.SSHPrivateKey,
})
}
return c.HandlerForExistingRepository()
return c.GitPull()
}
// isRepositoryExists checks for the existence of this past existence of this repository
func (c GitConfig) isRepositoryExists() (bool, error) {
func (c MyHubConfig) isRepositoryExists() (bool, error) {
RepoPath := GetClonePath(c)
_, err := os.Stat(RepoPath)
if err != nil {
@ -115,90 +162,25 @@ func (c GitConfig) isRepositoryExists() (bool, error) {
return true, nil
}
// HandlerForNonExistingRepository calls function GitPlainClone, which is called only when the repository exists
func (c GitConfig) HandlerForNonExistingRepository() error {
func (c MyHubConfig) setterRepositoryWorktreeReference() (*git.Repository, *git.Worktree, *plumbing.Reference, error) {
RepoPath := GetClonePath(c)
var referenceName plumbing.ReferenceName
referenceName = plumbing.NewBranchReferenceName(c.Branch)
_, err := git.PlainClone(RepoPath, false, &git.CloneOptions{
URL: c.RepositoryURL, Progress: os.Stdout,
ReferenceName: referenceName,
})
repository, err := git.PlainOpen(RepoPath)
if err != nil {
return fmt.Errorf("unable to clone '%s' reference of chaos-chart, err: %+v", c.Branch, err)
return nil, nil, nil, fmt.Errorf("error in executing PlainOpen: %s", err)
}
return nil
}
// HandlerForExistingRepository relative functions if the isRepositoryExists fails
func (c GitConfig) HandlerForExistingRepository() error {
dirtyStatus, err := c.GitGetStatus()
workTree, err := repository.Worktree()
if err != nil {
return err
return nil, nil, nil, fmt.Errorf("error in executing Worktree: %s", err)
}
log.WithFields(log.Fields{"DirtyStatus": dirtyStatus}).Info("Executed GitGetStatus()... ")
if dirtyStatus {
return c.HandlerForDirtyStatus()
}
return c.HandlerForCleanStatus()
}
// GitGetStatus excutes "git get status --porcelain" for the provided Repository Path,
// returns false if the repository is clean
// and true if the repository is dirtygitConfig
func (c GitConfig) GitGetStatus() (bool, error) {
err := c.setterRepositoryWorktreeReference()
plumbingRef, err := repository.Head()
if err != nil {
return true, err
return nil, nil, nil, fmt.Errorf("error in executing Head: %s", err)
}
// git status --porcelain
len, _ := getListofFilesChanged()
return !(len == 0), nil
}
func (c GitConfig) setterRepositoryWorktreeReference() error {
RepoPath := GetClonePath(c)
if repository, err = git.PlainOpen(RepoPath); err != nil {
return fmt.Errorf("error in executing PlainOpen: %s", err)
}
if workTree, err = repository.Worktree(); err != nil {
return fmt.Errorf("error in executing Worktree: %s", err)
}
plumbingRef, err = repository.Head()
if err != nil {
return fmt.Errorf("error in executing Head: %s", err)
}
return nil
}
// HandlerForDirtyStatus calls relative functions if the GitGetStatus gives a clean status as a result
func (c GitConfig) HandlerForDirtyStatus() error {
if err := c.GitHardReset(); err != nil {
return err
}
MatchValue, err := c.CompareLocalandRemoteCommit()
if err != nil {
return err
}
log.WithFields(log.Fields{"MatchValue": MatchValue}).Info("Executed CompareLocalandRemoteCommit()... ")
if !MatchValue {
return c.HandlerForMismatchCommits()
}
return nil
}
func getListofFilesChanged() (int, error) {
status, err := workTree.Status()
if err != nil {
return 0, fmt.Errorf("error in executing Status: %s", err)
}
var listOfFilesChanged []string
for file := range status {
listOfFilesChanged = append(listOfFilesChanged, file)
}
return len(listOfFilesChanged), nil
return repository, workTree, plumbingRef, nil
}
// GitHardReset executes "git reset --hard HEAD" in provided Repository Path
func (c GitConfig) GitHardReset() error {
func (c MyHubConfig) GitHardReset() error {
RepoPath := GetClonePath(c)
repository, err := git.PlainOpen(RepoPath)
if err != nil {
@ -215,7 +197,7 @@ func (c GitConfig) GitHardReset() error {
}
// CompareLocalandRemoteCommit compares local and remote latest commit
func (c GitConfig) CompareLocalandRemoteCommit() (bool, error) {
func (c MyHubConfig) CompareLocalandRemoteCommit() (bool, error) {
RepoPath := GetClonePath(c)
repository, err := git.PlainOpen(RepoPath)
if err != nil {
@ -230,36 +212,55 @@ func (c GitConfig) CompareLocalandRemoteCommit() (bool, error) {
}
// GitPull updates the repository in provided Path
func (c GitConfig) GitPull() error {
err := c.setterRepositoryWorktreeReference()
func (c MyHubConfig) GitPull() error {
_, workTree, plumbingRef, err := c.setterRepositoryWorktreeReference()
if err != nil {
return err
}
var referenceName plumbing.ReferenceName
referenceName = plumbing.NewBranchReferenceName(c.Branch)
err = workTree.Pull(&git.PullOptions{RemoteName: c.RemoteName, ReferenceName: referenceName})
c.LocalCommit = strings.Split(plumbingRef.String(), " ")[0]
if !c.IsPrivate {
err = workTree.Pull(&git.PullOptions{RemoteName: c.RemoteName, ReferenceName: referenceName})
if err == git.NoErrAlreadyUpToDate {
log.Print("Already up-to-date")
return nil
} else if err != nil {
return err
}
c.LocalCommit = strings.Split(plumbingRef.String(), " ")[0]
return nil
}
err = c.gitPullPrivateRepo()
if err == git.NoErrAlreadyUpToDate {
log.Print("Already up-to-date")
return nil
} else if err != nil {
return err
}
return nil
}
// HandlerForCleanStatus calls relative functions if the GitGetStatus gives a clean status as a result
func (c GitConfig) HandlerForCleanStatus() error {
MatchValue, err := c.CompareLocalandRemoteCommit()
// gitPullPrivateRepo updates the repository of private hubs
func (c MyHubConfig) gitPullPrivateRepo() error {
_, workTree, _, err := c.setterRepositoryWorktreeReference()
if err != nil {
return err
}
log.WithFields(log.Fields{"MatchValue": MatchValue}).Info("Executed CompareLocalandRemoteCommit()... ")
if !MatchValue {
err := c.GitPull()
if err != nil {
return err
}
var referenceName plumbing.ReferenceName
referenceName = plumbing.NewBranchReferenceName(c.Branch)
auth, err := c.generateAuthMethod()
if err != nil {
return nil
}
err = workTree.Pull(&git.PullOptions{RemoteName: c.RemoteName, ReferenceName: referenceName, Auth: auth})
if err != nil {
return err
}
return nil
}
// HandlerForMismatchCommits calls relative functions if the Local and Remote Commits do not match
func (c GitConfig) HandlerForMismatchCommits() error {
func (c MyHubConfig) HandlerForMismatchCommits() error {
err := c.GitPull()
if err != nil {
return err
@ -267,3 +268,28 @@ func (c GitConfig) HandlerForMismatchCommits() error {
log.WithFields(log.Fields{"execution": "complete"}).Info("Executed GitPull()... ")
return nil
}
// generateAuthMethod creates AuthMethod for private repos
func (c MyHubConfig) generateAuthMethod() (transport.AuthMethod, error) {
var auth transport.AuthMethod
if c.AuthType == model.AuthTypeToken {
auth = &http.BasicAuth{
Username: "kubera", // this can be anything except an empty string
Password: *c.Token,
}
} else if c.AuthType == model.AuthTypeBasic {
auth = &http.BasicAuth{
Username: *c.UserName,
Password: *c.Password,
}
} else if c.AuthType == model.AuthTypeSSH {
publicKey, err := ssh.NewPublicKeys("git", []byte(*c.SSHPrivateKey), "")
if err != nil {
return nil, err
}
auth = publicKey
auth.(*ssh.PublicKeys).HostKeyCallback = ssh2.InsecureIgnoreHostKey()
}
return auth, nil
}

View File

@ -0,0 +1,80 @@
package gitops
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"log"
"golang.org/x/crypto/ssh"
)
// GenerateKeys ...
func GenerateKeys() (string, string, error) {
bitSize := 4096
privateKey, err := generatePrivateKey(bitSize)
if err != nil {
return "", "", err
}
publicKeyBytes, err := generatePublicKey(&privateKey.PublicKey)
if err != nil {
return "", "", err
}
privateKeyBytes := encodePrivateKeyToPEM(privateKey)
return string(publicKeyBytes), string(privateKeyBytes), nil
}
// generatePrivateKey creates a RSA Private Key of specified byte size
func generatePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
// Private Key generation
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
return nil, err
}
// Validate Private Key
err = privateKey.Validate()
if err != nil {
return nil, err
}
log.Println("Private Key generated")
return privateKey, nil
}
// encodePrivateKeyToPEM encodes Private Key from RSA to PEM format
func encodePrivateKeyToPEM(privateKey *rsa.PrivateKey) []byte {
// Get ASN.1 DER format
privDER := x509.MarshalPKCS1PrivateKey(privateKey)
// pem.Block
privBlock := pem.Block{
Type: "RSA PRIVATE KEY",
Headers: nil,
Bytes: privDER,
}
// Private key in PEM format
privatePEM := pem.EncodeToMemory(&privBlock)
return privatePEM
}
// generatePublicKey take a rsa.PublicKey and return bytes suitable for writing to .pub file
// returns in the format "ssh-rsa ..."
func generatePublicKey(privatekey *rsa.PublicKey) ([]byte, error) {
publicRsaKey, err := ssh.NewPublicKey(privatekey)
if err != nil {
return nil, err
}
pubKeyBytes := ssh.MarshalAuthorizedKey(publicRsaKey)
log.Println("Public key generated")
return pubKeyBytes, nil
}

View File

@ -3,12 +3,15 @@ package myhub
import (
"context"
"errors"
"fmt"
"github.com/google/uuid"
"github.com/jinzhu/copier"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/graph/model"
database "github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/operations"
dbSchema "github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/schema"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/myhub/gitops"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/myhub/handler"
"go.mongodb.org/mongo-driver/bson"
"log"
"strconv"
"time"
@ -26,10 +29,16 @@ func AddMyHub(ctx context.Context, myhub model.CreateMyHub, projectID string) (*
}
cloneHub := model.CloningInput{
ProjectID: projectID,
RepoBranch: myhub.RepoBranch,
RepoURL: myhub.RepoURL,
HubName: myhub.HubName,
ProjectID: projectID,
RepoBranch: myhub.RepoBranch,
RepoURL: myhub.RepoURL,
HubName: myhub.HubName,
IsPrivate: myhub.IsPrivate,
UserName: myhub.UserName,
Password: myhub.Password,
AuthType: myhub.AuthType,
Token: myhub.Token,
SSHPrivateKey: myhub.SSHPrivateKey,
}
//Cloning the repository at a path from myhub link structure.
@ -41,13 +50,22 @@ func AddMyHub(ctx context.Context, myhub model.CreateMyHub, projectID string) (*
//Initialize a UID for new Hub.
uuid := uuid.New()
newHub := &dbSchema.MyHub{
ID: uuid.String(),
ProjectID: projectID,
RepoURL: myhub.RepoURL,
RepoBranch: myhub.RepoBranch,
HubName: myhub.HubName,
CreatedAt: strconv.FormatInt(time.Now().Unix(), 10),
UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10),
ID: uuid.String(),
ProjectID: projectID,
RepoURL: myhub.RepoURL,
RepoBranch: myhub.RepoBranch,
HubName: myhub.HubName,
IsPrivate: myhub.IsPrivate,
AuthType: string(myhub.AuthType),
Token: myhub.Token,
UserName: myhub.UserName,
Password: myhub.Password,
SSHPrivateKey: myhub.SSHPrivateKey,
SSHPublicKey: myhub.SSHPublicKey,
IsRemoved: false,
CreatedAt: strconv.FormatInt(time.Now().Unix(), 10),
UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10),
LastSyncedAt: strconv.FormatInt(time.Now().Unix(), 10),
}
//Adding the new hub into database with the given username.
@ -60,6 +78,48 @@ func AddMyHub(ctx context.Context, myhub model.CreateMyHub, projectID string) (*
return newHub.GetOutputMyHub(), nil
}
//SaveMyHub is used for Adding a new MyHub
func SaveMyHub(ctx context.Context, myhub model.CreateMyHub, projectID string) (*model.MyHub, error) {
IsExist, err := IsMyHubAvailable(ctx, myhub.HubName, projectID)
if err != nil {
return nil, err
}
if IsExist == true {
return nil, errors.New("HubName Already exists")
}
//Initialize a UID for new Hub.
uuid := uuid.New()
newHub := &dbSchema.MyHub{
ID: uuid.String(),
ProjectID: projectID,
RepoURL: myhub.RepoURL,
RepoBranch: myhub.RepoBranch,
HubName: myhub.HubName,
IsPrivate: myhub.IsPrivate,
AuthType: string(myhub.AuthType),
Token: myhub.Token,
UserName: myhub.UserName,
Password: myhub.Password,
SSHPrivateKey: myhub.SSHPrivateKey,
SSHPublicKey: myhub.SSHPublicKey,
IsRemoved: false,
CreatedAt: strconv.FormatInt(time.Now().Unix(), 10),
UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10),
LastSyncedAt: strconv.FormatInt(time.Now().Unix(), 10),
}
//Adding the new hub into database with the given username without cloning.
err = database.CreateMyHub(ctx, newHub)
if err != nil {
log.Print("ERROR", err)
return nil, err
}
return newHub.GetOutputMyHub(), nil
}
//HubStatus returns the array of hubdetails with their current status.
func HubStatus(ctx context.Context, projectID string) ([]*model.MyHubStatus, error) {
@ -90,12 +150,21 @@ func HubStatus(ctx context.Context, projectID string) ([]*model.MyHubStatus, err
}
}
hubDetail = &model.MyHubStatus{
IsAvailable: isConfirmed,
ID: hub.ID,
RepoURL: hub.RepoURL,
HubName: hub.HubName,
RepoBranch: hub.RepoBranch,
TotalExp: strconv.Itoa(sum),
IsAvailable: isConfirmed,
ID: hub.ID,
RepoURL: hub.RepoURL,
HubName: hub.HubName,
RepoBranch: hub.RepoBranch,
IsPrivate: hub.IsPrivate,
AuthType: model.AuthType(hub.AuthType),
Token: hub.Token,
UserName: hub.UserName,
Password: hub.Password,
SSHPrivateKey: hub.SSHPrivateKey,
SSHPublicKey: hub.SSHPublicKey,
IsRemoved: hub.IsRemoved,
LastSyncedAt: hub.LastSyncedAt,
TotalExp: strconv.Itoa(sum),
}
hubDetails = append(hubDetails, hubDetail)
}
@ -163,23 +232,39 @@ func GetExperiment(ctx context.Context, experimentInput model.ExperimentInput) (
}
//SyncHub is used for syncing the hub again if some not present or some error happens.
func SyncHub(ctx context.Context, projectID string, hubName string) ([]*model.MyHubStatus, error) {
syncHubInput := model.CloningInput{}
myhubs, err := database.GetMyHubByProjectID(ctx, projectID)
for _, n := range myhubs {
if n.HubName == hubName {
syncHubInput = model.CloningInput{
HubName: hubName,
ProjectID: projectID,
RepoURL: n.RepoURL,
RepoBranch: n.RepoBranch,
}
}
func SyncHub(ctx context.Context, hubID string) ([]*model.MyHubStatus, error) {
myhub, err := database.GetHubByID(ctx, hubID)
if err != nil {
return nil, err
}
syncHubInput := model.CloningInput{
HubName: myhub.HubName,
ProjectID: myhub.ProjectID,
RepoURL: myhub.RepoURL,
RepoBranch: myhub.RepoBranch,
IsPrivate: myhub.IsPrivate,
UserName: myhub.UserName,
Password: myhub.Password,
AuthType: model.AuthType(myhub.AuthType),
Token: myhub.Token,
SSHPrivateKey: myhub.SSHPrivateKey,
}
time := strconv.FormatInt(time.Now().Unix(), 10)
query := bson.D{{"myhub_id", hubID}, {"IsRemoved", false}}
update := bson.D{{"$set", bson.D{{"last_synced_at", time}}}}
err = gitops.GitSyncHandlerForProjects(syncHubInput)
if err != nil {
return nil, err
}
//Updating the last_synced_at time using hubID
err = database.UpdateMyHub(ctx, query, update)
if err != nil {
log.Print("ERROR", err)
return nil, err
}
return HubStatus(ctx, syncHubInput.ProjectID)
}
@ -208,3 +293,72 @@ func GetAllHubs(ctx context.Context) ([]*model.MyHub, error) {
return outputMyHubs, nil
}
func UpdateMyHub(ctx context.Context, myhub model.UpdateMyHub, projectID string) (*model.MyHub, error) {
cloneHub := model.CloningInput{
ProjectID: projectID,
RepoBranch: myhub.RepoBranch,
RepoURL: myhub.RepoURL,
HubName: myhub.HubName,
IsPrivate: myhub.IsPrivate,
UserName: myhub.UserName,
Password: myhub.Password,
AuthType: myhub.AuthType,
Token: myhub.Token,
SSHPrivateKey: myhub.SSHPrivateKey,
}
prevMyHub, err := database.GetHubByID(ctx, myhub.ID)
if err != nil {
return nil, err
}
// Syncing/Cloning the repository at a path from myhub link structure.
if prevMyHub.RepoURL != myhub.RepoURL || prevMyHub.RepoBranch != myhub.RepoBranch || prevMyHub.IsPrivate != myhub.IsPrivate || prevMyHub.AuthType != myhub.AuthType.String() {
fmt.Println(myhub.AuthType.String())
err := gitops.GitClone(cloneHub)
if err != nil {
return nil, err
}
} else {
err := gitops.GitSyncHandlerForProjects(cloneHub)
if err != nil {
return nil, err
}
}
time := strconv.FormatInt(time.Now().Unix(), 10)
query := bson.D{{"myhub_id", myhub.ID}, {"IsRemoved", false}}
update := bson.D{{"$set", bson.D{{"repo_url", myhub.RepoURL}, {"repo_branch", myhub.RepoBranch},
{"hub_name", myhub.HubName}, {"IsPrivate", myhub.IsPrivate}, {"AuthType", myhub.AuthType},
{"Token", myhub.Token}, {"UserName", myhub.UserName}, {"Password", myhub.Password},
{"SSHPrivateKey", myhub.SSHPrivateKey}, {"SSHPublicKey", myhub.SSHPublicKey}, {"updated_at", time}}}}
//Updating the new hub into database with the given username.
err = database.UpdateMyHub(ctx, query, update)
if err != nil {
log.Print("ERROR", err)
return nil, err
}
var newMyhub model.MyHub
copier.Copy(&newMyhub, &myhub)
newMyhub.UpdatedAt = time
return &newMyhub, nil
}
func DeleteMyHub(ctx context.Context, hubID string) (bool, error) {
query := bson.D{{"myhub_id", hubID}}
update := bson.D{{"$set", bson.D{{"IsRemoved", true}, {"updated_at", strconv.FormatInt(time.Now().Unix(), 10)}}}}
err := database.UpdateMyHub(ctx, query, update)
if err != nil {
log.Print("ERROR", err)
return false, err
}
return true, nil
}

View File

@ -22,10 +22,16 @@ func RecurringHubSync() {
for _, myhub := range myhubs {
chartsInput := model.CloningInput{
HubName: myhub.HubName,
ProjectID: myhub.ProjectID,
RepoURL: myhub.RepoURL,
RepoBranch: myhub.RepoBranch,
HubName: myhub.HubName,
ProjectID: myhub.ProjectID,
RepoURL: myhub.RepoURL,
RepoBranch: myhub.RepoBranch,
IsPrivate: myhub.IsPrivate,
AuthType: myhub.AuthType,
Token: myhub.Token,
UserName: myhub.UserName,
Password: myhub.Password,
SSHPrivateKey: myhub.SSHPrivateKey,
}
gitops.GitSyncHandlerForProjects(chartsInput)