-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provides the ability to generate a new operator with: `kudo package new foo` Also provides a way to generate a new operator interactively with `kudo package new -i foo Signed-off-by: Ken Sipe <kensipe@gmail.com>
- Loading branch information
Showing
11 changed files
with
526 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package generate | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"path" | ||
|
||
"github.com/spf13/afero" | ||
"sigs.k8s.io/yaml" | ||
|
||
"github.com/kudobuilder/kudo/pkg/apis/kudo/v1beta1" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/packages" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/packages/reader" | ||
) | ||
|
||
// CanGenerateOperator checks to see if operator generation makes sense (we don't generate over an operator or existing folder) | ||
// fails if folder exits (non-destructive) | ||
// if "operator.yaml" exists in current dir, we assume it's a mistake an error | ||
func CanGenerateOperator(fs afero.Fs, dir string, overwrite bool) error { | ||
exists, err := afero.Exists(fs, dir) | ||
if err != nil { | ||
return err | ||
} | ||
if exists && !overwrite { | ||
return fmt.Errorf("folder %q already exists", dir) | ||
} | ||
|
||
exists, err = afero.Exists(fs, reader.OperatorFileName) | ||
if err != nil { | ||
return err | ||
} | ||
if exists { | ||
return errors.New("operator.yaml exists in the current directory. creating an operator in an operator is not supported") | ||
} | ||
return nil | ||
} | ||
|
||
// Operator generates an initial operator folder with a operator.yaml | ||
func Operator(fs afero.Fs, dir string, op packages.OperatorFile, overwrite bool) error { | ||
err := CanGenerateOperator(fs, dir, overwrite) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
exists, err := afero.DirExists(fs, dir) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !exists { | ||
err = fs.Mkdir(dir, 0755) | ||
} | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// required empty settings | ||
op.Tasks = []v1beta1.Task{} | ||
op.Plans = make(map[string]v1beta1.Plan) | ||
|
||
err = writeOperator(fs, dir, op) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
pfname := path.Join(dir, reader.ParamsFileName) | ||
exists, err = afero.Exists(fs, pfname) | ||
if err != nil { | ||
return err | ||
} | ||
if exists { | ||
return nil | ||
} | ||
|
||
// if params doesn't exist create it | ||
p := packages.ParamsFile{ | ||
APIVersion: reader.APIVersion, | ||
Parameters: []v1beta1.Parameter{}, | ||
} | ||
return writeParameters(fs, dir, p) | ||
} | ||
|
||
func writeParameters(fs afero.Fs, dir string, params packages.ParamsFile) error { | ||
p, err := yaml.Marshal(params) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fname := path.Join(dir, reader.ParamsFileName) | ||
return afero.WriteFile(fs, fname, p, 0755) | ||
} | ||
|
||
func writeOperator(fs afero.Fs, dir string, op packages.OperatorFile) error { | ||
o, err := yaml.Marshal(op) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fname := path.Join(dir, reader.OperatorFileName) | ||
return afero.WriteFile(fs, fname, o, 0755) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package generate | ||
|
||
import ( | ||
"path" | ||
"testing" | ||
|
||
"github.com/spf13/afero" | ||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/kudobuilder/kudo/pkg/apis/kudo/v1beta1" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/packages" | ||
"github.com/kudobuilder/kudo/pkg/kudoctl/packages/reader" | ||
) | ||
|
||
func TestOperatorGenSafe(t *testing.T) { | ||
|
||
// empty fs should be fine | ||
fs := afero.NewMemMapFs() | ||
err := CanGenerateOperator(fs, "operator", false) | ||
assert.Nil(t, err) | ||
|
||
// folder that doesn't exist should be fine | ||
err = CanGenerateOperator(fs, "operator", false) | ||
assert.Nil(t, err) | ||
|
||
_ = fs.Mkdir("operator", 0755) | ||
// folder that exist should fail | ||
err = CanGenerateOperator(fs, "operator", false) | ||
assert.NotNil(t, err) | ||
|
||
// folder that exist should not fail if overwrite | ||
err = CanGenerateOperator(fs, "operator", true) | ||
assert.Nil(t, err) | ||
} | ||
|
||
var ( | ||
op1 = packages.OperatorFile{ | ||
Name: "foo", | ||
APIVersion: reader.APIVersion, | ||
Version: "0.1.0", | ||
} | ||
opFilename = path.Join("operator", "operator.yaml") | ||
paramFilename = path.Join("operator", "params.yaml") | ||
) | ||
|
||
func TestOperator_Write(t *testing.T) { | ||
|
||
fs := afero.NewMemMapFs() | ||
|
||
err := Operator(fs, "operator", op1, false) | ||
// no error on create | ||
assert.Nil(t, err) | ||
|
||
// results in operator file | ||
exists, _ := afero.Exists(fs, opFilename) | ||
assert.True(t, exists) | ||
// results in params file | ||
exists, _ = afero.Exists(fs, paramFilename) | ||
assert.True(t, exists) | ||
|
||
// test fail on existing | ||
err = Operator(fs, "operator", op1, false) | ||
assert.Errorf(t, err, "folder 'operator' already exists") | ||
|
||
// test overwriting with no error | ||
err = Operator(fs, "operator", op1, true) | ||
// no error on overwrite | ||
assert.Nil(t, err) | ||
|
||
// updating params file and testing params are not overwritten | ||
pf := packages.ParamsFile{ | ||
APIVersion: "FOO", | ||
Parameters: []v1beta1.Parameter{}, | ||
} | ||
// replace param file with a marker "FOO" to test that we do NOT overwrite it | ||
err = writeParameters(fs, "operator", pf) | ||
assert.Nil(t, err) | ||
// test overwriting with no error | ||
err = Operator(fs, "operator", op1, true) | ||
// no error on overwrite | ||
assert.Nil(t, err) | ||
parmfile, _ := afero.ReadFile(fs, paramFilename) | ||
assert.Contains(t, string(parmfile), "FOO") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.