Skip to content

Commit

Permalink
feat: add debug prep scripts and configuration for server (#1104)
Browse files Browse the repository at this point in the history
  • Loading branch information
tommartensen authored Dec 22, 2023
1 parent e09f8b2 commit a2cb69d
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 12 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ configuration/
tags
nohup.out
test/mocks
__debug_bin
__debug_bin*
.DS_Store
16 changes: 15 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@
"env": {
// "INFRA_TOKEN": "ALTERNATIVE_INFRA_TOKEN"
}
}
},
{
"name": "Debug Server",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "cmd/infra-server/main.go",
"args": [
"-config-dir", "../../configuration/"
],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "../../configuration/google_credentials.json",
"TEST_MODE": "true",
},
},
]
}
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,10 @@ install-argo: pre-check
.PHONY: clean-argo-config
clean-argo-config: pre-check
kubectl delete configmap argo-workflows-workflow-controller-configmap -n argo || true

###############
## Debugging ##
###############
.PHONY: prepare-local-server-debugging
prepare-local-server-debugging:
@./scripts/local-dev/prepare.sh
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,26 @@ toolchain, it is also possible to rely on CI. CI will lint, build and push the
infra server. And then deploy it to a development cluster created using the
production infra deployment. A
(comment)[https://github.com/stackrox/infra/pull/711#issuecomment-1270457578]
will appear on PRs with more detail.
will appear on PRs with more detail.

### Debugging

If opened in VS Code, you will find configurations for debugging CLI and Server.

#### CLI

To debug a CLI command, update the VS Code launch configuration "Debug CLI" with the desired command and update the `INFRA_TOKEN` value if necessary.
You may also point to a different infra server with the `--endpoint` flag.

#### Server

To debug the server, you need to fulfil the prerequisites first.

1. Have an authenticated `gcloud` CLI and GNU `sed` installed.
1. Have your `KUBECONFIG` point to a cluster where Argo Workflows and the ConfigMaps and Secrets for infra are deployed. This is most easily achieved by connecting to a PR cluster or deploying infra with `ENVIRONMENT=<DEVELOPMENT,PRODUCTION> make install-argo clean-argo-config helm-deploy` to a new or local cluster. This cluster will only be used to run workflows.
1. Run `make prepare-local-server-debugging` to set the contents of the `configuration` directory and compile the UI + CLI (for downloads).

Then, you can use the "Debug Server" launch configuration.

### Regenerate Go bindings from protos

Expand Down
4 changes: 3 additions & 1 deletion cmd/infra-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ func mainCmd() error {
func() (middleware.APIService, error) {
return service.NewUserService(oidc.GenerateServiceAccountToken)
},
service.NewCliService,
func() (middleware.APIService, error) {
return service.NewCliService(cfg.Server.StaticDir)
},
service.NewStatusService,
service.NewVersionService,
func() (middleware.APIService, error) {
Expand Down
5 changes: 5 additions & 0 deletions scripts/local-dev/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/stackrox/infra/scripts/local-dev

go 1.20

require gopkg.in/yaml.v2 v2.4.0 // indirect
3 changes: 3 additions & 0 deletions scripts/local-dev/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
162 changes: 162 additions & 0 deletions scripts/local-dev/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package main

import (
"encoding/base64"
"fmt"
"os"
"path/filepath"
"strings"
"text/template"

"gopkg.in/yaml.v2"
)

var localConfigurationDir = "configuration/"

func createLocalConfigurationDir() error {
// remove previous configurations
err := os.RemoveAll(localConfigurationDir)
if err != nil {
return fmt.Errorf("error while deleting the local configuration directory: %v", err)
}

// create clean configuration directory
err = os.MkdirAll(localConfigurationDir, os.ModePerm)
if err != nil {
return fmt.Errorf("error occurred creating the local configuration directory: %v", err)
}

return nil
}

func readFileToMap(path string) (map[string]string, error) {
data := make(map[string]string)
fileContent, err := os.ReadFile(path)
if err != nil {
return nil, err
}

err = yaml.Unmarshal(fileContent, &data)
if err != nil {
return nil, err
}

return data, nil
}

func getPathFromKey(key string) string {
// replace __ with / for directories
filepath := strings.Join(strings.Split(key, "__"), "/")
// replace last _ with . for file ending
index := strings.LastIndex(filepath, "_")
if index != -1 {
return filepath[:index] + "." + filepath[index+1:]
}

return filepath
}

func determineValues() (map[string]interface{}, error) {
values := map[string]interface{}{
"Values": map[string]interface{}{
"testMode": true,
},
}

data := make(map[string]interface{})
fileContent, err := os.ReadFile("chart/infra-server/Chart.yaml")
if err != nil {
return nil, err
}

err = yaml.Unmarshal(fileContent, &data)
if err != nil {
return nil, err
}

values["Chart"] = map[string]interface{}{
"Annotations": data["annotations"],
}

return values, nil
}

func renderFile(path, content string, decodeString bool) error {
configPath := fmt.Sprintf("%s%s", localConfigurationDir, path)
dir := filepath.Dir(configPath)
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {
return fmt.Errorf("error while creating directories: %v", err)
}

if decodeString {
decodedContent, err := base64.StdEncoding.DecodeString(content)
if err != nil {
return fmt.Errorf("error while decoding base64 content: %v", err)
}
content = string(decodedContent)
}

// Use a simple template engine to render the template
tmpl, err := template.New("template").Parse(content)
if err != nil {
return fmt.Errorf("error while parsing the template: %v", err)
}

outputFile, err := os.Create(configPath)
if err != nil {
return fmt.Errorf("error while creating the output file: %v", err)
}
defer outputFile.Close()

values, err := determineValues()
if err != nil {
return fmt.Errorf("An error occurred while determining values: %v", err)
}
err = tmpl.Execute(outputFile, values)
if err != nil {
return fmt.Errorf("An error occurred while rendering the template: %v", err)
}

return nil
}

func renderFlavors() error {
path := "flavors.yaml"
fileContent, err := os.ReadFile(fmt.Sprintf("chart/infra-server/static/%s", path))
if err != nil {
return err
}
return renderFile(path, string(fileContent), false)
}

func main() {
if err := createLocalConfigurationDir(); err != nil {
fmt.Printf("Error: %v\n", err)
return
}

data, err := readFileToMap("chart/infra-server/configuration/development-values-from-files.yaml")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}

for key, content := range data {
filepath := getPathFromKey(key)
err := renderFile(filepath, content, true)
if err != nil {
fmt.Printf("Error creating file %s: %v\n", filepath, err)
return
} else {
fmt.Println("Created", filepath)
}
}

if err := renderFlavors(); err != nil {
fmt.Printf("Error: %v\n", err)
return
} else {
fmt.Println("Created flavors.yaml")
}
}
30 changes: 30 additions & 0 deletions scripts/local-dev/prepare.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

set -euo pipefail

if ! sed --version | grep -q GNU; then
echo "Only GNU sed is supported"
exit 1
fi

echo "INFO: Download secrets"
ENVIRONMENT=development make secrets-download

echo "INFO: Place configuration with rendered values"
go run scripts/local-dev/main.go

echo "INFO: Replace /configuration/ -> ../../configuration/ in infra.yaml"
sed -i 's/\/configuration\//..\/..\/configuration\/tls\//g' configuration/infra.yaml
echo "INFO: Replace configuration/ -> ../../configuration/ in flavors.yaml"
sed -i 's/configuration\//..\/..\/configuration\//g' configuration/flavors.yaml

echo "INFO: Replace /etc/infra/static -> ../../ui/build in infra.yaml"
sed -i 's/\/etc\/infra\/static/..\/..\/ui\/build/g' configuration/infra.yaml

echo "INFO: Copy workflow templates in place"
cp chart/infra-server/static/{test,workflow}-*.yaml configuration/

echo "Prepare UI + CLI (for downloads)"
make -C ui
make cli
cp -R bin ui/build/downloads
10 changes: 6 additions & 4 deletions service/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import (

const bufferSize = 1000 * 1024

type cliImpl struct{}
type cliImpl struct {
staticDir string
}

var (
log = logging.CreateProductionLogger()
Expand All @@ -25,8 +27,8 @@ var (
)

// NewCliService creates a new CliUpgradeService.
func NewCliService() (middleware.APIService, error) {
return &cliImpl{}, nil
func NewCliService(staticDir string) (middleware.APIService, error) {
return &cliImpl{staticDir: staticDir}, nil
}

// Upgrade provides the binary for the requested OS and architecture.
Expand All @@ -36,7 +38,7 @@ func (s *cliImpl) Upgrade(request *v1.CliUpgradeRequest, stream v1.CliService_Up
return err
}

filename := webRoot + "/downloads/infractl-" + request.GetOs() + "-" + request.GetArch()
filename := s.staticDir + "/downloads/infractl-" + request.GetOs() + "-" + request.GetArch()
file, err := os.Open(filename)
if err != nil {
log.Log(logging.ERROR, "failed to open infractl binary", "error", err)
Expand Down
4 changes: 0 additions & 4 deletions service/package.go

This file was deleted.

0 comments on commit a2cb69d

Please sign in to comment.