Skip to content

Commit

Permalink
Merge branch 'main' into am/skip-minors-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
AminSlk authored Aug 16, 2024
2 parents a4bddf3 + 77403eb commit 4553132
Show file tree
Hide file tree
Showing 28 changed files with 1,189 additions and 117 deletions.
70 changes: 70 additions & 0 deletions cli/pkg/cli_utils/http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*This file is part of kuberpult.
Kuberpult is free software: you can redistribute it and/or modify
it under the terms of the Expat(MIT) License as published by
the Free Software Foundation.
Kuberpult is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MIT License for more details.
You should have received a copy of the MIT License
along with kuberpult. If not, see <https://directory.fsf.org/wiki/License:Expat>.
Copyright freiheit.com*/

package cli_utils

import (
"fmt"
"io"
"log"
"net/http"
"time"
)

const (
HttpDefaultTimeout = 180
)

func doRequest(request *http.Request) (*http.Response, []byte, error) {
//exhaustruct:ignore
client := &http.Client{
Timeout: HttpDefaultTimeout * time.Second,
}

resp, err := client.Do(request)
if err != nil {
return nil, nil, fmt.Errorf("error issuing the HTTP request, error: %w", err)
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, nil, fmt.Errorf("unable to read response: %v with error: %w", resp, err)
}

return resp, body, nil
}

func IssueHttpRequest(req http.Request, retries uint64) error {
var i uint64
for i = 0; i < retries+1; i++ {
response, body, err := doRequest(&req)
if err != nil {
log.Printf("error issuing http request: %v\n", err)
} else if response.StatusCode != http.StatusCreated && response.StatusCode != http.StatusOK {
log.Printf("Recieved response code %d - %s from Kuberpult\nResponse body:\n%s\n", response.StatusCode, http.StatusText(response.StatusCode), string(body))
} else {
log.Printf("Success: %d - %s\nResponse body:\n%s\n", response.StatusCode, http.StatusText(response.StatusCode), string(body))
return nil
}
if i < retries {
backoff := time.Duration(i+1) * time.Second
log.Printf("Retrying in %v...\n", backoff)
time.Sleep(backoff)
}
}
return fmt.Errorf("could not perform a successful call to kuberpult")
}
4 changes: 4 additions & 0 deletions cli/pkg/cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ func RunCLI() ReturnCode {
return ReturnCodeSuccess
case "release":
return handleRelease(*kpClientParams, subflags)
case "create-env-lock":
return handleCreateEnvLock(*kpClientParams, subflags)
case "create-app-lock":
return handleCreateAppLock(*kpClientParams, subflags)
default:
log.Printf("unknown subcommand %s\n", subcommand)
return ReturnCodeInvalidArguments
Expand Down
45 changes: 44 additions & 1 deletion cli/pkg/cmd/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Copyright freiheit.com*/
package cmd

import (
"github.com/freiheit-com/kuberpult/cli/pkg/cli_utils"
"github.com/freiheit-com/kuberpult/cli/pkg/locks"
"log"

kutil "github.com/freiheit-com/kuberpult/cli/pkg/kuberpult_utils"
Expand All @@ -41,7 +43,7 @@ func handleRelease(kpClientParams kuberpultClientParameters, args []string) Retu
requestParameters := kutil.RequestParameters{
Url: &kpClientParams.url,
Retries: kpClientParams.retries,
HttpTimeout: rl.DefaultTimeout,
HttpTimeout: cli_utils.HttpDefaultTimeout,
}

if err = rl.Release(requestParameters, authParams, *parsedArgs); err != nil {
Expand All @@ -50,3 +52,44 @@ func handleRelease(kpClientParams kuberpultClientParameters, args []string) Retu
}
return ReturnCodeSuccess
}

func handleCreateEnvLock(kpClientParams kuberpultClientParameters, args []string) ReturnCode {
parsedArgs, err := locks.ParseArgsCreateEnvironmentLock(args)

if err != nil {
log.Printf("error while parsing command line args, error: %v", err)
return ReturnCodeInvalidArguments
}
return handleCreateLock(kpClientParams, parsedArgs)
}

func handleCreateAppLock(kpClientParams kuberpultClientParameters, args []string) ReturnCode {
parsedArgs, err := locks.ParseArgsCreateAppLock(args)

if err != nil {
log.Printf("error while parsing command line args, error: %v", err)
return ReturnCodeInvalidArguments
}
return handleCreateLock(kpClientParams, parsedArgs)
}

func handleCreateLock(kpClientParams kuberpultClientParameters, parsedArgs locks.LockParameters) ReturnCode {
authParams := kutil.AuthenticationParameters{
IapToken: kpClientParams.iapToken,
DexToken: kpClientParams.dexToken,
AuthorName: kpClientParams.authorName,
AuthorEmail: kpClientParams.authorEmail,
}

requestParameters := kutil.RequestParameters{
Url: &kpClientParams.url,
Retries: kpClientParams.retries,
HttpTimeout: cli_utils.HttpDefaultTimeout,
}

if err := locks.CreateLock(requestParameters, authParams, parsedArgs); err != nil {
log.Printf("error creating lock, error: %v", err)
return ReturnCodeFailure
}
return ReturnCodeSuccess
}
106 changes: 106 additions & 0 deletions cli/pkg/locks/app_lock_parsing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*This file is part of kuberpult.
Kuberpult is free software: you can redistribute it and/or modify
it under the terms of the Expat(MIT) License as published by
the Free Software Foundation.
Kuberpult is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MIT License for more details.
You should have received a copy of the MIT License
along with kuberpult. If not, see <https://directory.fsf.org/wiki/License:Expat>.
Copyright freiheit.com*/

package locks

import (
"flag"
"fmt"
"strings"

"github.com/freiheit-com/kuberpult/cli/pkg/cli_utils"
)

type CreateAppLockCommandLineArguments struct {
environment cli_utils.RepeatedString
lockId cli_utils.RepeatedString
message cli_utils.RepeatedString
application cli_utils.RepeatedString
useDexAuthentication bool
}

func argsValidCreateAppLock(cmdArgs *CreateAppLockCommandLineArguments) (result bool, errorMessage string) {
if len(cmdArgs.lockId.Values) != 1 {
return false, "the --lockID arg must be set exactly once"
}
if len(cmdArgs.environment.Values) != 1 {
return false, "the --environment arg must be set exactly once"
}
if len(cmdArgs.application.Values) != 1 {
return false, "the --application arg must be set exactly once"
}
if len(cmdArgs.message.Values) > 1 {
return false, "the --message arg must be set at most once"
}

return true, ""
}

func readCreateAppLockArgs(args []string) (*CreateAppLockCommandLineArguments, error) {
cmdArgs := CreateAppLockCommandLineArguments{} //exhaustruct:ignore

fs := flag.NewFlagSet("flag set", flag.ContinueOnError)

fs.Var(&cmdArgs.lockId, "lockID", "the ID of the lock you are trying to create")
fs.Var(&cmdArgs.environment, "environment", "the environment to lock")
fs.Var(&cmdArgs.message, "message", "lock message")
fs.Var(&cmdArgs.application, "application", "application to lock")
fs.BoolVar(&cmdArgs.useDexAuthentication, "use_dex_auth", false, "if set to true, the /api/* endpoint will be used. Dex must be enabled on the server side and a dex token must be provided, otherwise the request will be denied")

if err := fs.Parse(args); err != nil {
return nil, fmt.Errorf("error while parsing command line arguments, error: %w", err)
}

if len(fs.Args()) != 0 { // kuberpult-cli release does not accept any positional arguments, so this is an error
return nil, fmt.Errorf("these arguments are not recognized: \"%v\"", strings.Join(fs.Args(), " "))
}

if ok, msg := argsValidCreateAppLock(&cmdArgs); !ok {
return nil, fmt.Errorf(msg)
}

return &cmdArgs, nil
}

func convertToCreateAppLockParams(cmdArgs CreateAppLockCommandLineArguments) (LockParameters, error) {
if ok, msg := argsValidCreateAppLock(&cmdArgs); !ok {
return nil, fmt.Errorf("the provided command line arguments structure is invalid, cause: %s", msg)
}

rp := AppLockParameters{
LockId: cmdArgs.lockId.Values[0],
Environment: cmdArgs.environment.Values[0],
Application: cmdArgs.application.Values[0],
Message: "",
UseDexAuthentication: cmdArgs.useDexAuthentication,
}
if len(cmdArgs.message.Values) != 0 {
rp.Message = cmdArgs.message.Values[0]
}
return &rp, nil
}

func ParseArgsCreateAppLock(args []string) (LockParameters, error) {
cmdArgs, err := readCreateAppLockArgs(args)
if err != nil {
return nil, fmt.Errorf("error while reading command line arguments for creating an app lock, error: %w", err)
}
rp, err := convertToCreateAppLockParams(*cmdArgs)
if err != nil {
return nil, fmt.Errorf("error while creating parameters for creating an application lock, error: %w", err)
}
return rp, nil
}
Loading

0 comments on commit 4553132

Please sign in to comment.