Skip to content

Commit

Permalink
Merge pull request #29 from olttwa/master
Browse files Browse the repository at this point in the history
Remove redundant proc command to list/describe/execute procs
  • Loading branch information
olttwa authored Oct 12, 2018
2 parents dde43e8 + 11d35ba commit 9f17709
Show file tree
Hide file tree
Showing 23 changed files with 670 additions and 490 deletions.
20 changes: 0 additions & 20 deletions .env.test

This file was deleted.

31 changes: 1 addition & 30 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,6 @@ language: go
go:
- "1.10"

env:
global:
- ENVIRONMENT="test"
- PROCTOR_KUBE_CONFIG="out-of-cluster"
- PROCTOR_LOG_LEVEL="debug"
- PROCTOR_APP_PORT="5000"
- PROCTOR_DEFAULT_NAMESPACE="default"
- PROCTOR_REDIS_ADDRESS="localhost:6379"
- PROCTOR_REDIS_MAX_ACTIVE_CONNECTIONS="10"
- PROCTOR_KUBE_JOB_ACTIVE_DEADLINE_SECONDS="60"
- PROCTOR_KUBE_JOB_RETRIES="0"
- PROCTOR_LOGS_STREAM_READ_BUFFER_SIZE="140"
- PROCTOR_LOGS_STREAM_WRITE_BUFFER_SIZE="4096"
- PROCTOR_KUBE_CLUSTER_HOST_NAME="localhost:8001"
- PROCTOR_KUBE_POD_LIST_WAIT_TIME="5"
- PROCTOR_KUBE_CA_CERT_ENCODED="LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmNlcnRpZmljYXRlCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
- PROCTOR_KUBE_BASIC_AUTH="YWRtaW46cGFzc3dvcmQK"
- PROCTOR_POSTGRES_USER="postgres"
- PROCTOR_POSTGRES_PASSWORD=""
- PROCTOR_POSTGRES_HOST="localhost"
- PROCTOR_POSTGRES_PORT="5432"
- PROCTOR_POSTGRES_DATABASE="proctord_ci"
- PROCTOR_POSTGRES_MAX_CONNECTIONS="50"
- PROCTOR_POSTGRES_CONNECTIONS_MAX_LIFETIME="30"

services:
- redis-server
- postgresql
Expand All @@ -38,7 +13,6 @@ before_script:
- curl https://glide.sh/get | sh
# Start Redis sever
- sudo service redis-server start
- psql -c 'create database proctord_ci;' -U postgres

stages:
- test
Expand All @@ -49,10 +23,7 @@ jobs:
script:
# testing proctord
- cd proctord/
- glide install
- go build
- ./proctord migrate
- go test -race -cover $(glide novendor)
- make setup-test-teardown
# testing proctor cli
- cd ../.
- make ci.test
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Changelog
All notable changes to this project will be documented in this file.

## [WIP: v0.2.0] - 2018-10-10
## [WIP: v0.2.0] - 2018-10-11
### Added
- Configurable kubernetes job retries (on failure)
### Modified
- Changelog format
- CI golang version. Reason: [kubernetes client-go issue](https://github.com/kubernetes/client-go/issues/449)
### Removed
- Redundant typing of `proc` for listing, discribing and executing procs

## v0.1.0 - 2018-10-08
### Added
Expand Down
67 changes: 67 additions & 0 deletions cmd/description/descriptor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package description

import (
"fmt"
"net/http"

"github.com/fatih/color"
"github.com/gojektech/proctor/daemon"
"github.com/gojektech/proctor/io"
"github.com/gojektech/proctor/proc"
"github.com/gojektech/proctor/proctord/utility"
"github.com/spf13/cobra"
)

func NewCmd(printer io.Printer, proctorEngineClient daemon.Client) *cobra.Command {
return &cobra.Command{
Use: "describe",
Short: "Describe a proc, list help for variables and constants",
Long: "In order to execute a proc, you need to provide certain variables. Describe command helps you with those variables and their meanings/convention/usage, etc.",
Example: "proctor describe proc-one\nproctor describe proc-two",
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 1 {
printer.Println("Incorrect command. See `proctor describe --help` for usage", color.FgRed)
return
}

procList, err := proctorEngineClient.ListProcs()
if err != nil {
if err.Error() == http.StatusText(http.StatusUnauthorized) {
printer.Println(utility.UnauthorizedError, color.FgRed)
return
}

printer.Println(utility.GenericDescribeCmdError, color.FgRed)
return
}

desiredProc := proc.Metadata{}
for _, proc := range procList {
if args[0] == proc.Name {
desiredProc = proc
}
}
if len(desiredProc.Name) == 0 {
printer.Println(fmt.Sprintf("Proctor doesn't support proc: %s", args[0]), color.FgRed)
return
}

printer.Println(fmt.Sprintf("%-40s %-100s", "Proc Name", desiredProc.Name), color.Reset)
printer.Println(fmt.Sprintf("%-40s %-100s", "Proc Description", desiredProc.Description), color.Reset)
printer.Println(fmt.Sprintf("%-40s %-100s", "Contributors", desiredProc.Contributors), color.Reset)
printer.Println(fmt.Sprintf("%-40s %-100s", "Organization", desiredProc.Organization), color.Reset)

printer.Println("\nVariables", color.FgMagenta)
for _, arg := range desiredProc.EnvVars.Args {
printer.Println(fmt.Sprintf("%-40s %-100s", arg.Name, arg.Description), color.Reset)
}

printer.Println("\nConstants", color.FgMagenta)
for _, secret := range desiredProc.EnvVars.Secrets {
printer.Println(fmt.Sprintf("%-40s %-100s", secret.Name, secret.Description), color.Reset)
}

printer.Println("\nFor executing a proc, run:\nproctor execute <proc_name> <args_name>", color.FgGreen)
},
}
}
124 changes: 124 additions & 0 deletions cmd/description/descriptor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package description

import (
"errors"
"fmt"
"net/http"
"testing"

"github.com/fatih/color"
"github.com/gojektech/proctor/daemon"
"github.com/gojektech/proctor/io"
"github.com/gojektech/proctor/proc"
"github.com/gojektech/proctor/proc/env"
"github.com/gojektech/proctor/proctord/utility"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)

type DescribeCmdTestSuite struct {
suite.Suite
mockPrinter *io.MockPrinter
mockProctorEngineClient *daemon.MockClient
testDescribeCmd *cobra.Command
}

func (s *DescribeCmdTestSuite) SetupTest() {
s.mockPrinter = &io.MockPrinter{}
s.mockProctorEngineClient = &daemon.MockClient{}
s.testDescribeCmd = NewCmd(s.mockPrinter, s.mockProctorEngineClient)
}

func (s *DescribeCmdTestSuite) TestDescribeCmdUsage() {
assert.Equal(s.T(), "describe", s.testDescribeCmd.Use)
}

func (s *DescribeCmdTestSuite) TestDescribeCmdHelp() {
assert.Equal(s.T(), "Describe a proc, list help for variables and constants", s.testDescribeCmd.Short)
assert.Equal(s.T(), "In order to execute a proc, you need to provide certain variables. Describe command helps you with those variables and their meanings/convention/usage, etc.", s.testDescribeCmd.Long)
assert.Equal(s.T(), "proctor describe proc-one\nproctor describe proc-two", s.testDescribeCmd.Example)
}

func (s *DescribeCmdTestSuite) TestDescribeCmdRun() {
arg := env.VarMetadata{
Name: "arg-one",
Description: "arg one description",
}

secret := env.VarMetadata{
Name: "secret-one",
Description: "secret one description",
}

anyProc := proc.Metadata{
Name: "any-proc",
Description: "does something",
Contributors: "user@example.com",
Organization: "org",
EnvVars: env.Vars{
Args: []env.VarMetadata{arg},
Secrets: []env.VarMetadata{secret},
},
}
procList := []proc.Metadata{anyProc}

s.mockProctorEngineClient.On("ListProcs").Return(procList, nil).Once()

s.mockPrinter.On("Println", fmt.Sprintf("%-40s %-100s", "Proc Name", anyProc.Name), color.Reset).Once()
s.mockPrinter.On("Println", fmt.Sprintf("%-40s %-100s", "Proc Description", anyProc.Description), color.Reset).Once()
s.mockPrinter.On("Println", fmt.Sprintf("%-40s %-100s", "Contributors", anyProc.Contributors), color.Reset).Once()
s.mockPrinter.On("Println", fmt.Sprintf("%-40s %-100s", "Organization", anyProc.Organization), color.Reset).Once()
s.mockPrinter.On("Println", "\nVariables", color.FgMagenta).Once()
s.mockPrinter.On("Println", fmt.Sprintf("%-40s %-100s", arg.Name, arg.Description), color.Reset).Once()
s.mockPrinter.On("Println", "\nConstants", color.FgMagenta).Once()
s.mockPrinter.On("Println", fmt.Sprintf("%-40s %-100s", secret.Name, secret.Description), color.Reset).Once()
s.mockPrinter.On("Println", "\nFor executing a proc, run:\nproctor execute <proc_name> <args_name>", color.FgGreen).Once()

s.testDescribeCmd.Run(&cobra.Command{}, []string{"any-proc"})

s.mockProctorEngineClient.AssertExpectations(s.T())
s.mockPrinter.AssertExpectations(s.T())
}

func (s *DescribeCmdTestSuite) TestDescribeCmdForIncorrectUsage() {
s.mockPrinter.On("Println", "Incorrect command. See `proctor describe --help` for usage", color.FgRed).Once()

s.testDescribeCmd.Run(&cobra.Command{}, []string{})

s.mockPrinter.AssertExpectations(s.T())
}

func (s *DescribeCmdTestSuite) TestDescribeCmdRunProctorEngineClientFailure() {
s.mockProctorEngineClient.On("ListProcs").Return([]proc.Metadata{}, errors.New("error")).Once()
s.mockPrinter.On("Println", utility.GenericDescribeCmdError, color.FgRed).Once()

s.testDescribeCmd.Run(&cobra.Command{}, []string{"any-proc"})

s.mockProctorEngineClient.AssertExpectations(s.T())
s.mockPrinter.AssertExpectations(s.T())
}

func (s *DescribeCmdTestSuite) TestDescribeCmdRunProcNotSupported() {
s.mockProctorEngineClient.On("ListProcs").Return([]proc.Metadata{}, nil).Once()
s.mockPrinter.On("Println", fmt.Sprintf("Proctor doesn't support proc: %s", "any-proc"), color.FgRed).Once()

s.testDescribeCmd.Run(&cobra.Command{}, []string{"any-proc"})

s.mockProctorEngineClient.AssertExpectations(s.T())
s.mockPrinter.AssertExpectations(s.T())
}

func (s *DescribeCmdTestSuite) TestDescribeCmdRunProcForUnauthorizedUser() {
s.mockProctorEngineClient.On("ListProcs").Return([]proc.Metadata{}, errors.New(http.StatusText(http.StatusUnauthorized))).Once()
s.mockPrinter.On("Println", utility.UnauthorizedError, color.FgRed).Once()

s.testDescribeCmd.Run(&cobra.Command{}, []string{"any-proc"})

s.mockProctorEngineClient.AssertExpectations(s.T())
s.mockPrinter.AssertExpectations(s.T())
}

func TestDescribeCmdTestSuite(t *testing.T) {
suite.Run(t, new(DescribeCmdTestSuite))
}
71 changes: 71 additions & 0 deletions cmd/execution/executioner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package execution

import (
"fmt"
"net/http"
"strings"

"github.com/fatih/color"
"github.com/gojektech/proctor/daemon"
"github.com/gojektech/proctor/io"
"github.com/gojektech/proctor/proctord/utility"
"github.com/spf13/cobra"
)

func NewCmd(printer io.Printer, proctorEngineClient daemon.Client) *cobra.Command {
return &cobra.Command{
Use: "execute",
Short: "Execute a proc with arguments given",
Long: "To execute a proc, this command helps communicate with `proctord` and streams to logs of proc in execution",
Example: "proctor execute proc-one SOME_VAR=foo ANOTHER_VAR=bar\nproctor execute proc-two ANY_VAR=baz",

Run: func(cmd *cobra.Command, args []string) {
if len(args) < 1 {
printer.Println("Incorrect command. See `proctor execute --help` for usage", color.FgRed)
return
}

procName := args[0]
printer.Println(fmt.Sprintf("%-40s %-100s", "Executing Proc", procName), color.Reset)

procArgs := make(map[string]string)
if len(args) > 1 {
printer.Println("With Variables", color.FgMagenta)
for _, v := range args[1:] {
arg := strings.Split(v, "=")

if len(arg) < 2 {
printer.Println(fmt.Sprintf("%-40s %-100s", "\nIncorrect variable format\n", v), color.FgRed)
continue
}

combinedArgValue := strings.Join(arg[1:], "=")
procArgs[arg[0]] = combinedArgValue

printer.Println(fmt.Sprintf("%-40s %-100s", arg[0], combinedArgValue), color.Reset)
}
} else {
printer.Println("With No Variables", color.FgRed)
}

executedProcName, err := proctorEngineClient.ExecuteProc(procName, procArgs)
if err != nil {
if err.Error() == http.StatusText(http.StatusUnauthorized) {
printer.Println(utility.UnauthorizedError, color.FgRed)
return
}
printer.Println(utility.GenericProcCmdError, color.FgRed)
return
}

printer.Println("Proc execution successful. \nStreaming logs:", color.FgGreen)
err = proctorEngineClient.StreamProcLogs(executedProcName)
if err != nil {
printer.Println("Error Streaming Logs", color.FgRed)
return
}

printer.Println("Log stream of proc completed.", color.FgGreen)
},
}
}
Loading

0 comments on commit 9f17709

Please sign in to comment.