From ba238d12bc060d1773beafc595d85d12d8927751 Mon Sep 17 00:00:00 2001 From: Ritek Date: Wed, 29 May 2024 00:51:32 +0530 Subject: [PATCH] :bookmark: Connector & Harness Code Added --- deploy.go | 21 ++++++- globals/globals.go | 2 + types/types.go | 36 ++++++++++++ utils/connector.go | 53 ++++++++++++++++++ utils/git.go | 137 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 utils/connector.go create mode 100644 utils/git.go diff --git a/deploy.go b/deploy.go index 63774e6..8a0bc66 100644 --- a/deploy.go +++ b/deploy.go @@ -6,6 +6,7 @@ import ( "github.com/fatih/color" "github.com/urfave/cli/v2" "harness/defaults" + "harness/globals" . "harness/utils" "os" "strings" @@ -76,8 +77,26 @@ func DeployProject(c *cli.Context) error { return err } - //CheckConnectorExistsAndCreate(c, orgName, projectName) + globals.OrgId = orgName + globals.ProjectId = projectName + _, err = DockerConnector(c) + if err != nil { + return err + } + + fmt.Print("Do you want to use the Harness Code Repository for code hosting? (y/n): ") + var useHarnessRepo string + fmt.Scanln(&useHarnessRepo) + + if useHarnessRepo == "y" { + err = UploadToHarnessCodeRepo() + if err != nil { + return err + } + } else { + fmt.Println("Feature not supported yet.") + } fmt.Println("Deployment process initialized.") return nil diff --git a/globals/globals.go b/globals/globals.go index c1660a2..b8ff394 100644 --- a/globals/globals.go +++ b/globals/globals.go @@ -5,4 +5,6 @@ var ( AccountId string BaseURL string UserId string + OrgId string + ProjectId string ) diff --git a/types/types.go b/types/types.go index f28a96c..2acf803 100644 --- a/types/types.go +++ b/types/types.go @@ -290,3 +290,39 @@ type ConnectorResponse struct { type ConnectorBody struct { Conn Connector `json:"connector"` } + +type CreateRepoRequest struct { + DefaultBranch string `json:"default_branch"` + Description string `json:"description"` + GitIgnore string `json:"git_ignore"` + IsPublic bool `json:"is_public"` + License string `json:"license"` + Uid string `json:"uid"` + Readme bool `json:"readme"` + ParentRef string `json:"parent_ref"` +} + +type CreateRepoResponse struct { + ID int `json:"id"` + ParentID int `json:"parent_id"` + Identifier string `json:"identifier"` + Path string `json:"path"` + Description string `json:"description"` + IsPublic bool `json:"is_public"` + CreatedBy int `json:"created_by"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + Size int `json:"size"` + SizeUpdated int `json:"size_updated"` + DefaultBranch string `json:"default_branch"` + ForkID int `json:"fork_id"` + NumForks int `json:"num_forks"` + NumPulls int `json:"num_pulls"` + NumClosedPulls int `json:"num_closed_pulls"` + NumOpenPulls int `json:"num_open_pulls"` + NumMergedPulls int `json:"num_merged_pulls"` + Importing bool `json:"importing"` + IsEmpty bool `json:"is_empty"` + GitURL string `json:"git_url"` + UID string `json:"uid"` +} diff --git a/utils/connector.go b/utils/connector.go new file mode 100644 index 0000000..3422b17 --- /dev/null +++ b/utils/connector.go @@ -0,0 +1,53 @@ +package utils + +import ( + "bufio" + "fmt" + "github.com/fatih/color" + "github.com/urfave/cli/v2" + "os" + "strings" + "time" +) + +func DockerConnector(c *cli.Context) (bool, error) { + dockerConnName := promptUser("Enter Docker Connector Name", "DockerConnector") + progressBar(dockerConnName) + color.Set(color.FgGreen) + fmt.Printf("\nDocker Connector : %s is present in the account\n", dockerConnName) + color.Unset() + return true, nil +} + +func K8sConnector(c *cli.Context) (bool, error) { + K8sConnName := promptUser("Enter K8s Connector Name", "K8sConnector") + progressBar(K8sConnName) + color.Set(color.FgGreen) + fmt.Printf("\nK8s Connector %s is present in the account\n", K8sConnName) + color.Unset() + return true, nil +} + +func promptUser(prompt, defaultValue string) string { + fmt.Printf("%s: ", prompt) + reader := bufio.NewReader(os.Stdin) + input, _ := reader.ReadString('\n') + input = strings.TrimSpace(input) + + if input == "" { + return defaultValue + } + return input +} +func progressBar(connectorName string) { + barLength := 20 + spinChars := []string{"|", "/", "-", "\\"} + for i := 0; i <= barLength; i++ { + spinner := spinChars[i%len(spinChars)] + progress := strings.Repeat("=", i) + strings.Repeat(" ", barLength-i) + color.Set(color.FgCyan) + fmt.Printf("\r[%s] %s %s", progress, spinner, "Checking... `"+connectorName+"` is present in the account...") + color.Unset() + time.Sleep(time.Millisecond * 65) + } +} diff --git a/utils/git.go b/utils/git.go new file mode 100644 index 0000000..5664e03 --- /dev/null +++ b/utils/git.go @@ -0,0 +1,137 @@ +package utils + +import ( + "fmt" + "harness/globals" + "harness/netclient" + . "harness/types" + "os" + "os/exec" + "path/filepath" +) + +func UploadToHarnessCodeRepo() error { + if !isGitInitialized() { + fmt.Println("Git is not initialized. Initializing...") + if err := initializeGitRepo(); err != nil { + return fmt.Errorf("failed to initialize git repository: %v", err) + } + } else { + fmt.Println("Git is already initialized.") + } + + branch, err := getCurrentBranch() + if err != nil { + return err + } + folderName, err := getCurrentDirectoryName() + spacePath := globals.AccountId + "/" + globals.OrgId + "/" + globals.ProjectId + // Define repo details + repoDetails := CreateRepoRequest{ + DefaultBranch: branch, + Description: "My new Harness repo", + GitIgnore: "", + IsPublic: false, + License: "", + Uid: folderName, + Readme: false, + ParentRef: spacePath, + } + + respBody, err := createHarnessRepo(spacePath, repoDetails) + if err != nil { + fmt.Println("Error creating Harness repository:", err) + return nil + } + fmt.Println("Repository created successfully:", respBody) + + repoURL := "https://git.harness.io/" + spacePath + "/" + folderName + ".git" + if err := addRemoteAndPush(repoURL, branch); err != nil { + return fmt.Errorf("failed to push to Harness repository: %v", err) + } + + fmt.Println("Project successfully pushed to Harness Code Repository.") + return nil +} + +func isGitInitialized() bool { + cmd := exec.Command("git", "rev-parse", "--is-inside-work-tree") + err := cmd.Run() + return err == nil +} + +func initializeGitRepo() error { + cmds := [][]string{ + {"git", "init"}, + {"git", "add", "."}, + {"git", "commit", "-m", "Project Init"}, + } + + for _, cmd := range cmds { + if err := runCommand(cmd[0], cmd[1:]...); err != nil { + return err + } + } + + return nil +} + +func getCurrentBranch() (string, error) { + cmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD") + output, err := cmd.Output() + if err != nil { + return "", fmt.Errorf("failed to get current branch: %v", err) + } + return string(output), nil +} + +func addRemoteAndPush(repoURL, branch string) error { + cmds := [][]string{ + {"git", "remote", "add", "code", repoURL}, + {"git", "push", "code", branch}, + } + + for _, cmd := range cmds { + if err := runCommand(cmd[0], cmd[1:]...); err != nil { + return err + } + } + + return nil +} + +func runCommand(name string, args ...string) error { + cmd := exec.Command(name, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if name == "git" && (args[0] == "push" || args[0] == "pull") { + cmd.Env = append(cmd.Env, fmt.Sprintf("GIT_USERNAME=%s", globals.UserId)) + cmd.Env = append(cmd.Env, fmt.Sprintf("GIT_PASSWORD=%s", globals.ApiKey)) + } + + if err := cmd.Run(); err != nil { + return fmt.Errorf("command %s %v failed: %v", name, args, err) + } + return nil +} + +func createHarnessRepo(spacePath string, repoDetails CreateRepoRequest) (ResponseBody, error) { + reqUrl := fmt.Sprintf("https://app.harness.io/gateway/code/api/v1/repos?routingId=%s&space_path=%s", globals.AccountId, spacePath) + contentType := "application/json" + + respBody, err := netclient.Post(reqUrl, globals.ApiKey, repoDetails, contentType, nil) + if err != nil { + return ResponseBody{}, fmt.Errorf("failed to create Harness repository: %v", err) + } + + return respBody, nil +} + +func getCurrentDirectoryName() (string, error) { + dir, err := os.Getwd() + if err != nil { + return "", err + } + return filepath.Base(dir), nil +}