mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
Merge pull request #13 from kadel/ocClient
[Work In Progress] First take on OcClient
This commit is contained in:
@@ -16,6 +16,8 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -35,6 +37,17 @@ var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Print the version of ocdev",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
// If verbose mode is enabled, dump all KUBECLT_* env variables
|
||||
// this is usefull for debuging oc plugin integration
|
||||
if GlobalVerbose {
|
||||
for _, v := range os.Environ() {
|
||||
if strings.HasPrefix(v, "KUBECTL_") {
|
||||
fmt.Println(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(VERSION + " (" + GITCOMMIT + ")")
|
||||
},
|
||||
}
|
||||
|
||||
132
pkg/occlient/occlient.go
Normal file
132
pkg/occlient/occlient.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package occlient
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
type OcClient struct {
|
||||
// full path to oc binary
|
||||
oc string
|
||||
}
|
||||
|
||||
// NewOcClient creates new instance of OcClient
|
||||
// parameters oc is full path to oc client binary
|
||||
func NewOcClient(oc string) (*OcClient, error) {
|
||||
if _, err := os.Stat(oc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &OcClient{
|
||||
oc: oc,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
// runOcCommands executes oc
|
||||
// args - command line arguments to be passed to oc ('-o json' is added by default if data is not nil)
|
||||
// data - is a pointer to a string, if set than data is given to command to stdin ('-f -' is added to args as default)
|
||||
func (occlient *OcClient) runOcComamnd(args []string, data *string) ([]byte, error) {
|
||||
|
||||
cmd := exec.Command(occlient.oc, args...)
|
||||
|
||||
// if data is not set assume that it is get command
|
||||
if data == nil {
|
||||
cmd.Args = append(cmd.Args, "-o", "json")
|
||||
} else {
|
||||
// data is given, assume this is crate or apply command
|
||||
// that takes data from stdin
|
||||
cmd.Args = append(cmd.Args, "-f", "-")
|
||||
|
||||
// Read from stdin
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Write to stdin
|
||||
go func() {
|
||||
defer stdin.Close()
|
||||
_, err := io.WriteString(stdin, *data)
|
||||
if err != nil {
|
||||
fmt.Printf("can't write to stdin %v\n", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Execute the actual command
|
||||
var stdOut, stdErr bytes.Buffer
|
||||
cmd.Stdout = &stdOut
|
||||
cmd.Stderr = &stdErr
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
outputMessage := ""
|
||||
if stdErr.Len() != 0 {
|
||||
outputMessage = stdErr.String()
|
||||
}
|
||||
if stdOut.Len() != 0 {
|
||||
outputMessage = fmt.Sprintf("\n%s", stdErr.String())
|
||||
}
|
||||
|
||||
if outputMessage != "" {
|
||||
return nil, fmt.Errorf("failed to execute oc command\n %s", outputMessage)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if stdErr.Len() != 0 {
|
||||
return nil, fmt.Errorf("Error output:\n%s", stdErr.String())
|
||||
}
|
||||
|
||||
return stdOut.Bytes(), nil
|
||||
|
||||
}
|
||||
|
||||
// // GetDeploymentConfig returns information about DeploymentConfig
|
||||
// func (occlient *OcClient) GetDeploymentConfig(name string) (*ov1.DeploymentConfig, error) {
|
||||
// args := []string{
|
||||
// "get",
|
||||
// "deploymentconfig",
|
||||
// name,
|
||||
// }
|
||||
|
||||
// output, err := occlient.runOcComamnd(args, nil)
|
||||
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// dc := &ov1.DeploymentConfig{}
|
||||
|
||||
// err = json.Unmarshal(output, dc)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// return dc, nil
|
||||
// }
|
||||
|
||||
// // CreateDeploymentConfig creates new DeploymentConfig
|
||||
// func (occlient *OcClient) CreateDeploymentConfig(dc *ov1.DeploymentConfig) error {
|
||||
// data, err := json.Marshal(dc)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// args := []string{
|
||||
// "create",
|
||||
// }
|
||||
|
||||
// stringData := string(data[:])
|
||||
// output, err := occlient.runOcComamnd(args, &stringData)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// fmt.Println(string(output[:]))
|
||||
// return nil
|
||||
// }
|
||||
61
pkg/occlient/occlient_test.go
Normal file
61
pkg/occlient/occlient_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package occlient
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewOcClient(t *testing.T) {
|
||||
|
||||
// test setup
|
||||
// test shouldn't have external dependency, so we are faking oc binary with empty tmpfile
|
||||
tmpfile, err := ioutil.TempFile("", "fake-oc")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer os.Remove(tmpfile.Name()) // clean up
|
||||
|
||||
type args struct {
|
||||
oc string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *OcClient
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "oc path exists",
|
||||
args: args{
|
||||
oc: tmpfile.Name(),
|
||||
},
|
||||
want: &OcClient{
|
||||
oc: tmpfile.Name(),
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "oc path doesn't exists",
|
||||
args: args{
|
||||
oc: "/non/existing",
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := NewOcClient(tt.args.oc)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("NewOcClient() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("NewOcClient() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user