Skip to content

Commit

Permalink
feat: Add Scaffold Command (kyma-project#1859)
Browse files Browse the repository at this point in the history
* feat: Add Scaffold Command

* feat: Add Docs

* feat: Add Docs

* docs(scaffold.go): Fix Long Description

* trigger build

* docs(scaffold.go): Update Md Files

* Update cmd/kyma/alpha/create/scaffold/scaffold.go

Co-authored-by: Małgorzata Świeca <[email protected]>

* Update cmd/kyma/alpha/create/scaffold/scaffold.go

Co-authored-by: Małgorzata Świeca <[email protected]>

* Update cmd/kyma/alpha/create/scaffold/scaffold.go

Co-authored-by: Małgorzata Świeca <[email protected]>

* Update docs/gen-docs/kyma_alpha_create.md

Co-authored-by: Małgorzata Świeca <[email protected]>

* Update cmd/kyma/alpha/create/scaffold/scaffold.go

Co-authored-by: Małgorzata Świeca <[email protected]>

* docs(scaffold.go): Update Md Files

* Merge Latest Changes

* Fix E2E Test

* scaffold.go: Fix Manifest and Default CR Generation

* default_cr.go: Fix Lint

* default_cr.go: Fix Metadata Case Sensitivity Issue

* scaffold.go: Fix Empty Directory Issue

* test-e2e-create-scaffold.yml: Add Newline At The End

* opts.go: Fix Overwrite Validation

* scaffold.go: Update Command Help

* Update Docs

* retrigger jobs

* Refactoring

* Refactoring

* Refactoring

* Refactoring

* Refactoring

* Refactoring

* Refactoring

* Refactoring

* Refactoring

* Add tests (WIP)

* Add tests (WIP)

* Add tests (WIP)

* Add tests (WIP)

* Add tests (WIP)

* Add tests (WIP)

* Add tests (WIP)

* Review fix

* Apply suggestions from code review

Co-authored-by: Oleksandr Meteiko <[email protected]>

* Review fix

* Review fix

* Review fix

* Review fix

* Review fix

* Review fix

* Review fix

* Review fix

---------

Co-authored-by: Małgorzata Świeca <[email protected]>
Co-authored-by: Benjamin Lindner <[email protected]>
Co-authored-by: Tomasz Smelcerz <[email protected]>
Co-authored-by: Oleksandr Meteiko <[email protected]>
  • Loading branch information
5 people authored Jan 15, 2024
1 parent 539e188 commit f1ed885
Show file tree
Hide file tree
Showing 18 changed files with 1,420 additions and 23 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/test-e2e-create-scaffold.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: TestSuite E2E. Scaffold Creation

on:
push:
branches:
- main
- 'release-**'
pull_request:
branches:
- main
- 'release-**'
paths:
- 'go.mod'
- 'go.sum'
- '**.go'
jobs:
e2e:
name: "Run E2E tests"
runs-on: ubuntu-latest
steps:
- name: Checkout Kyma CLI
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
cache-dependency-path: 'go.sum'
- name: Build Kyma CLI
run: |
make resolve validate build-linux
chmod +x ./bin/kyma-linux
ls -la ./bin
mv ./bin/kyma-linux /usr/local/bin/kyma
timeout-minutes: 10
- name: Run create scaffold test
run: |
make -C tests/e2e test-create-scaffold
timeout-minutes: 3
2 changes: 2 additions & 0 deletions cmd/kyma/alpha/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package create

import (
"github.com/kyma-project/cli/cmd/kyma/alpha/create/module"
"github.com/kyma-project/cli/cmd/kyma/alpha/create/scaffold"
"github.com/kyma-project/cli/internal/cli"
"github.com/spf13/cobra"
)
Expand All @@ -16,6 +17,7 @@ func NewCmd(o *cli.Options) *cobra.Command {
}

cmd.AddCommand(module.NewCmd(module.NewOptions(o)))
cmd.AddCommand(scaffold.NewCmd(scaffold.NewOptions(o)))

return cmd
}
28 changes: 14 additions & 14 deletions cmd/kyma/alpha/create/module/moduleconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ import (
)

type Config struct {
Name string `yaml:"name"` // required, the name of the Module
Version string `yaml:"version"` // required, the version of the Module
Channel string `yaml:"channel"` // required, channel that should be used in the ModuleTemplate
ManifestPath string `yaml:"manifest"` // required, reference to the manifests, must be a relative file name.
Mandatory bool `yaml:"mandatory"` // optional, default=false, indicates whether the module is mandatory to be installed on all clusters.
DefaultCRPath string `yaml:"defaultCR"` // optional, reference to a YAML file containing the default CR for the module, must be a relative file name.
ResourceName string `yaml:"resourceName"` // optional, default={NAME}-{CHANNEL}, the name for the ModuleTemplate that will be created
Namespace string `yaml:"namespace"` // optional, default=kcp-system, the namespace where the ModuleTemplate will be deployed
Security string `yaml:"security"` // optional, name of the security scanners config file
Internal bool `yaml:"internal"` // optional, default=false, determines whether the ModuleTemplate should have the internal flag or not
Beta bool `yaml:"beta"` // optional, default=false, determines whether the ModuleTemplate should have the beta flag or not
Labels map[string]string `yaml:"labels"` // optional, additional labels for the ModuleTemplate
Annotations map[string]string `yaml:"annotations"` // optional, additional annotations for the ModuleTemplate
CustomStateChecks []v1beta2.CustomStateCheck `yaml:"customStateCheck"` // optional, specifies custom state check for module
Name string `yaml:"name" comment:"required, the name of the Module"`
Version string `yaml:"version" comment:"required, the version of the Module"`
Channel string `yaml:"channel" comment:"required, channel that should be used in the ModuleTemplate"`
ManifestPath string `yaml:"manifest" comment:"required, reference to the manifests, must be a relative file name"`
Mandatory bool `yaml:"mandatory" comment:"optional, default=false, indicates whether the module is mandatory to be installed on all clusters"`
DefaultCRPath string `yaml:"defaultCR" comment:"optional, reference to a YAML file containing the default CR for the module, must be a relative file name"`
ResourceName string `yaml:"resourceName" comment:"optional, default={NAME}-{CHANNEL}, the name for the ModuleTemplate that will be created"`
Namespace string `yaml:"namespace" comment:"optional, default=kcp-system, the namespace where the ModuleTemplate will be deployed"`
Security string `yaml:"security" comment:"optional, name of the security scanners config file"`
Internal bool `yaml:"internal" comment:"optional, default=false, determines whether the ModuleTemplate should have the internal flag or not"`
Beta bool `yaml:"beta" comment:"optional, default=false, determines whether the ModuleTemplate should have the beta flag or not"`
Labels map[string]string `yaml:"labels" comment:"optional, additional labels for the ModuleTemplate"`
Annotations map[string]string `yaml:"annotations" comment:"optional, additional annotations for the ModuleTemplate"`
CustomStateChecks []v1beta2.CustomStateCheck `yaml:"customStateCheck" comment:"optional, specifies custom state check for module"`
}

const (
Expand Down
105 changes: 105 additions & 0 deletions cmd/kyma/alpha/create/scaffold/opts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package scaffold

import (
"fmt"
"os"
"path"

"github.com/kyma-project/cli/internal/cli"
"github.com/pkg/errors"
)

// Options specifies the flags for the scaffold command
type Options struct {
*cli.Options

Overwrite bool
Directory string

ModuleConfigFile string
ManifestFile string
SecurityConfigFile string
DefaultCRFile string

ModuleName string
ModuleVersion string
ModuleChannel string
}

func (o *Options) securityConfigFileConfigured() bool {
return o.SecurityConfigFile != ""
}

func (o *Options) defaultCRFileConfigured() bool {
return o.DefaultCRFile != ""
}

var (
errDirNotExists = errors.New("provided directory does not exist")
errNotDirectory = errors.New("provided path is not a directory")
errModuleConfigExists = errors.New("module config file already exists. use --overwrite flag to overwrite it")
errModuleNameEmpty = errors.New("--module-name flag must not be empty")
errModuleVersionEmpty = errors.New("--module-version flag must not be empty")
errModuleChannelEmpty = errors.New("--module-channel flag must not be empty")
errManifestFileEmpty = errors.New("--gen-manifest flag must not be empty")
errModuleConfigEmpty = errors.New("--module-config flag must not be empty")
errManifestCreation = errors.New("could not generate manifest")
errDefaultCRCreationFailed = errors.New("could not generate default CR")
errModuleConfigCreationFailed = errors.New("could not generate module config")
errSecurityConfigCreationFailed = errors.New("could not generate security config")
)

// NewOptions creates options with default values
func NewOptions(o *cli.Options) *Options {
return &Options{Options: o}
}

func (o *Options) Validate() error {
if o.ModuleName == "" {
return errModuleNameEmpty
}

if o.ModuleVersion == "" {
return errModuleVersionEmpty
}

if o.ModuleChannel == "" {
return errModuleChannelEmpty
}

err := o.validateDirectory()
if err != nil {
return err
}

if o.ModuleConfigFile == "" {
return errModuleConfigEmpty
}

if o.ManifestFile == "" {
return errManifestFileEmpty
}

return nil
}

func (o *Options) validateDirectory() error {
fi, err := os.Stat(o.Directory)

if err != nil {
if errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("%w: %s", errDirNotExists, o.Directory)
}
return err
}

if !fi.IsDir() {
return fmt.Errorf("%w: %s", errNotDirectory, o.Directory)
}

return nil
}

func (o *Options) getCompleteFilePath(fileName string) string {
return path.Join(o.Directory, fileName)
}
Loading

0 comments on commit f1ed885

Please sign in to comment.