Skip to content

Commit 2425824

Browse files
committed
Merge branch 'release/v1.41.0'
2 parents 98deae8 + 58b3f97 commit 2425824

File tree

6 files changed

+263
-6
lines changed

6 files changed

+263
-6
lines changed

client/endpoint.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package client
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"fmt"
7+
"github.com/spf13/viper"
8+
"io"
9+
"mime/multipart"
10+
"net/http"
11+
"net/url"
12+
"os"
13+
"path/filepath"
14+
15+
"github.com/kondukto-io/kdt/klog"
16+
)
17+
18+
func (c *Client) ImportEndpoint(filePath string, projectName string) error {
19+
klog.Debugf("importing endpoint using file:%s", filePath)
20+
21+
if filePath == "" {
22+
return errors.New("file parameter is required")
23+
}
24+
25+
projectDoc, err := c.FindProjectByName(projectName)
26+
if err != nil || projectDoc == nil {
27+
return fmt.Errorf("no projects found for name [%s]", projectName)
28+
}
29+
30+
if _, err := os.Stat(filePath); os.IsNotExist(err) {
31+
return fmt.Errorf("file does not exist: %s", filePath)
32+
}
33+
34+
path := fmt.Sprintf("/api/v2/projects/%s/apispecs", projectDoc.ID)
35+
rel := &url.URL{Path: path}
36+
u := c.BaseURL.ResolveReference(rel)
37+
38+
body := &bytes.Buffer{}
39+
writer := multipart.NewWriter(body)
40+
41+
file, err := os.Open(filePath)
42+
if err != nil {
43+
return fmt.Errorf("failed to open file: %w", err)
44+
}
45+
defer file.Close()
46+
47+
part, err := writer.CreateFormFile("file", filepath.Base(filePath))
48+
if err != nil {
49+
return fmt.Errorf("failed to create form file: %w", err)
50+
}
51+
52+
if _, err = io.Copy(part, file); err != nil {
53+
return fmt.Errorf("failed to copy file content: %w", err)
54+
}
55+
56+
if err = writer.Close(); err != nil {
57+
return fmt.Errorf("failed to close writer: %w", err)
58+
}
59+
60+
req, err := http.NewRequest(http.MethodPost, u.String(), body)
61+
if err != nil {
62+
return fmt.Errorf("failed to create request: %w", err)
63+
}
64+
65+
req.Header.Set("Content-Type", writer.FormDataContentType())
66+
req.Header.Set("Accept", "application/json")
67+
req.Header.Set("User-Agent", userAgent)
68+
req.Header.Set("X-Cookie", viper.GetString("token"))
69+
70+
resp, err := c.do(req, nil)
71+
if err != nil {
72+
return fmt.Errorf("request failed: %w", err)
73+
}
74+
75+
if resp.StatusCode != http.StatusOK {
76+
return fmt.Errorf("failed to import endpoint: %s", resp.Status)
77+
}
78+
79+
return nil
80+
}

client/projects.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ func (c *Client) FindProjectByName(name string) (*Project, error) {
9191

9292
type ProjectDetail struct {
9393
Name string `json:"name"`
94-
Source ProjectSource `json:"source"`
95-
Team ProjectTeam `json:"team"`
94+
Source *ProjectSource `json:"source"`
95+
Team *ProjectTeam `json:"team"`
9696
Labels []ProjectLabel `json:"labels"`
9797
Override bool `json:"override"` // That means, if the project already exists, create a new one with suffix "-"
9898
Overwrite bool `json:"overwrite"` // That means, if the project already exists, overwrite it
@@ -104,7 +104,7 @@ type ProjectDetail struct {
104104
// FeatureBranchInfiniteRetention holds a value that disables the feature branch retention period.
105105
FeatureBranchInfiniteRetention bool `json:"feature_branch_no_retention"`
106106
DefaultBranch string `json:"default_branch"`
107-
CriticalityLevel int `json:"criticality_level"`
107+
CriticalityLevel *int `json:"criticality_level"`
108108
}
109109

110110
type ProjectSource struct {
@@ -266,3 +266,17 @@ func (c *Client) IsAvailable(project, almTool string) (bool, error) {
266266

267267
return checkProjectResponse.Exist, nil
268268
}
269+
270+
func (c *Client) Update(projectID string, pd ProjectDetail) error {
271+
req, err := c.newRequest(http.MethodPatch, fmt.Sprintf("/api/v2/projects/%s", projectID), pd)
272+
if err != nil {
273+
return err
274+
}
275+
276+
_, err = c.do(req, nil)
277+
if err != nil {
278+
return err
279+
}
280+
281+
return nil
282+
}

cmd/createProjects.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ func (p *Project) createProject(repo, projectName string, force bool, overwrite
246246

247247
pd := client.ProjectDetail{
248248
Name: overwriteName,
249-
Source: projectSource,
250-
Team: client.ProjectTeam{
249+
Source: &projectSource,
250+
Team: &client.ProjectTeam{
251251
Name: team,
252252
},
253253
Labels: parsedLabels,
@@ -257,7 +257,7 @@ func (p *Project) createProject(repo, projectName string, force bool, overwrite
257257
FeatureBranchRetention: featureBranchRetention,
258258
FeatureBranchInfiniteRetention: featureBranchNoRetention,
259259
DefaultBranch: defaultBranch,
260-
CriticalityLevel: businessCriticalityLevel,
260+
CriticalityLevel: &businessCriticalityLevel,
261261
}
262262

263263
project, err := p.client.CreateProject(pd)

cmd/endpoint.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package cmd
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"github.com/spf13/cobra"
7+
8+
"github.com/kondukto-io/kdt/client"
9+
"github.com/kondukto-io/kdt/klog"
10+
)
11+
12+
// endpointCmd represents the endpoint root command
13+
var endpointCmd = &cobra.Command{
14+
Use: "endpoint",
15+
Short: "base command for endpoint (swagger, open-api) imports",
16+
}
17+
18+
// importEndpointCmd represents the endpoint import command
19+
var importEndpointCmd = &cobra.Command{
20+
Use: "import",
21+
Short: "imports endpoint file to Kondukto",
22+
RunE: importEndpointRootCommand,
23+
PreRunE: func(cmd *cobra.Command, args []string) error {
24+
if !cmd.Flags().Changed("file") {
25+
return errors.New("file flag is required")
26+
}
27+
if !cmd.Flags().Changed("project") {
28+
return errors.New("project flag is required")
29+
}
30+
return nil
31+
},
32+
}
33+
34+
func init() {
35+
rootCmd.AddCommand(endpointCmd)
36+
endpointCmd.AddCommand(importEndpointCmd)
37+
38+
importEndpointCmd.Flags().StringP("file", "f", "", "endpoint file to be imported")
39+
importEndpointCmd.Flags().StringP("project", "p", "", "Kondukto project id or name")
40+
41+
_ = importEndpointCmd.MarkFlagRequired("file")
42+
_ = importEndpointCmd.MarkFlagRequired("project")
43+
}
44+
45+
func importEndpointRootCommand(cmd *cobra.Command, args []string) error {
46+
c, err := client.New()
47+
if err != nil {
48+
return fmt.Errorf("could not initialize Kondukto client: %w", err)
49+
}
50+
51+
file, err := cmd.Flags().GetString("file")
52+
if err != nil {
53+
return fmt.Errorf("failed to parse file flag: %w", err)
54+
}
55+
56+
projectName, err := getSanitizedFlagStr(cmd, "project")
57+
if err != nil {
58+
return fmt.Errorf("failed to get project flag: %w", err)
59+
}
60+
61+
if err := c.ImportEndpoint(file, projectName); err != nil {
62+
return fmt.Errorf("failed to import endpoint file: %w", err)
63+
}
64+
65+
klog.Printf("endpoint file [%s] imported successfully", file)
66+
return nil
67+
}

cmd/update.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package cmd
2+
3+
import "github.com/spf13/cobra"
4+
5+
// updateCmd represents the create command
6+
var updateCmd = &cobra.Command{
7+
Use: "update",
8+
Short: "base command for update",
9+
Run: func(cmd *cobra.Command, args []string) {
10+
if len(args) == 0 {
11+
_ = cmd.Help()
12+
qwm(ExitCodeSuccess, "")
13+
}
14+
},
15+
}
16+
17+
func init() {
18+
rootCmd.AddCommand(updateCmd)
19+
}

cmd/updateProjects.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/kondukto-io/kdt/client"
7+
"github.com/kondukto-io/kdt/klog"
8+
9+
"github.com/spf13/cobra"
10+
)
11+
12+
func init() {
13+
updateCmd.AddCommand(updateProjectCMD)
14+
updateProjectCMD.Flags().String("project-id", "", "id of the project")
15+
updateProjectCMD.Flags().Int("criticality-level", 0, "business criticality of the project, possible values are [ 4 = Major, 3 = High, 2 = Medium, 1 = Low, 0 = None, -1 = Auto ]. Default is [0]")
16+
}
17+
18+
// updateBCCMd represents the sbom import command
19+
var updateProjectCMD = &cobra.Command{
20+
Use: "project",
21+
Short: "updates the project on Kondukto",
22+
Run: updateProjectBaseCommand,
23+
}
24+
25+
func updateProjectBaseCommand(cmd *cobra.Command, _ []string) {
26+
// Initialize Kondukto client
27+
c, err := client.New()
28+
if err != nil {
29+
qwe(ExitCodeError, err, "could not initialize Kondukto client")
30+
}
31+
bc := ProjectUpdate{
32+
cmd: cmd,
33+
client: c,
34+
}
35+
if err = bc.Update(); err != nil {
36+
qwe(ExitCodeError, err, "failed to update project")
37+
}
38+
}
39+
40+
type ProjectUpdate struct {
41+
cmd *cobra.Command
42+
client *client.Client
43+
}
44+
45+
func (p *ProjectUpdate) Update() error {
46+
projectID, err := getSanitizedFlagStr(p.cmd, "project-id")
47+
if err != nil {
48+
return fmt.Errorf("failed to get project flag: %w", err)
49+
}
50+
51+
level, err := p.cmd.Flags().GetInt("criticality-level")
52+
if err != nil {
53+
return fmt.Errorf("failed to parse level flag: %w", err)
54+
}
55+
56+
var hasUpdate bool
57+
var pd = new(client.ProjectDetail)
58+
59+
if p.cmd.Flags().Changed("criticality-level") {
60+
pd.CriticalityLevel = &level
61+
hasUpdate = true
62+
}
63+
64+
if !hasUpdate {
65+
klog.Println("mo update flags found, no updates will be made")
66+
return nil
67+
}
68+
69+
err = p.client.Update(projectID, *pd)
70+
if err != nil {
71+
return fmt.Errorf("failed to update project: %w", err)
72+
}
73+
74+
klog.Printf("project is successfully updated for: [%s]", projectID)
75+
76+
return nil
77+
}

0 commit comments

Comments
 (0)