Merge "New CLI option to get/set manifest"
This commit is contained in:
commit
901c314f02
@ -51,5 +51,8 @@ func NewConfigCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Comma
|
||||
configRootCmd.AddCommand(NewInitCommand(rootSettings))
|
||||
configRootCmd.AddCommand(NewUseContextCommand(rootSettings))
|
||||
|
||||
configRootCmd.AddCommand(NewGetManifestCommand(rootSettings))
|
||||
configRootCmd.AddCommand(NewSetManifestCommand(rootSettings))
|
||||
|
||||
return configRootCmd
|
||||
}
|
||||
|
76
cmd/config/get_manifest.go
Normal file
76
cmd/config/get_manifest.go
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
)
|
||||
|
||||
const (
|
||||
getManifestsLong = `
|
||||
Display a specific manifest information, or all defined manifests if no name is provided.
|
||||
`
|
||||
|
||||
getManifestsExample = `
|
||||
# List all the manifests airshipctl knows about
|
||||
airshipctl config get-manifests
|
||||
|
||||
# Display a specific manifest
|
||||
airshipctl config get-manifest e2e
|
||||
`
|
||||
)
|
||||
|
||||
// NewGetManifestCommand creates a command for viewing the manifest information
|
||||
// defined in the airshipctl config file.
|
||||
func NewGetManifestCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
|
||||
o := &config.ManifestOptions{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "get-manifest NAME",
|
||||
Short: "Get a manifest information from the airshipctl config",
|
||||
Long: getManifestsLong[1:],
|
||||
Example: getManifestsExample,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Aliases: []string{"get-manifests"},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
airconfig := rootSettings.Config
|
||||
if len(args) == 1 {
|
||||
o.Name = args[0]
|
||||
manifest, exists := airconfig.Manifests[o.Name]
|
||||
if !exists {
|
||||
return config.ErrMissingConfig{
|
||||
What: fmt.Sprintf("Manifest with name '%s'", o.Name),
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(cmd.OutOrStdout(), manifest)
|
||||
} else {
|
||||
manifests := airconfig.GetManifests()
|
||||
if len(manifests) == 0 {
|
||||
fmt.Fprintln(cmd.OutOrStdout(), "No Manifest found in the configuration.")
|
||||
}
|
||||
for _, manifest := range manifests {
|
||||
fmt.Fprintln(cmd.OutOrStdout(), manifest)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
75
cmd/config/get_manifest_test.go
Normal file
75
cmd/config/get_manifest_test.go
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
cmd "opendev.org/airship/airshipctl/cmd/config"
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
"opendev.org/airship/airshipctl/testutil"
|
||||
)
|
||||
|
||||
func TestGetManifestConfigCmd(t *testing.T) {
|
||||
settings := &environment.AirshipCTLSettings{
|
||||
Config: &config.Config{
|
||||
Manifests: map[string]*config.Manifest{
|
||||
"fooManifestConfig": getTestManifest("foo"),
|
||||
"barManifestConfig": getTestManifest("bar"),
|
||||
"bazManifestConfig": getTestManifest("baz"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
noConfigSettings := &environment.AirshipCTLSettings{Config: new(config.Config)}
|
||||
|
||||
cmdTests := []*testutil.CmdTest{
|
||||
{
|
||||
Name: "get-manifest",
|
||||
CmdLine: "fooManifestConfig",
|
||||
Cmd: cmd.NewGetManifestCommand(settings),
|
||||
},
|
||||
{
|
||||
Name: "get-all-manifests",
|
||||
CmdLine: "",
|
||||
Cmd: cmd.NewGetManifestCommand(settings),
|
||||
},
|
||||
{
|
||||
Name: "missing",
|
||||
CmdLine: "manifestMissing",
|
||||
Cmd: cmd.NewGetManifestCommand(settings),
|
||||
Error: fmt.Errorf("Missing configuration: Manifest with name 'manifestMissing'"),
|
||||
},
|
||||
{
|
||||
Name: "no-manifests",
|
||||
CmdLine: "",
|
||||
Cmd: cmd.NewGetManifestCommand(noConfigSettings),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cmdTests {
|
||||
testutil.RunTest(t, tt)
|
||||
}
|
||||
}
|
||||
|
||||
func getTestManifest(name string) *config.Manifest {
|
||||
manifests := &config.Manifest{
|
||||
PrimaryRepositoryName: name + "_primary_repo",
|
||||
TargetPath: name + "_target_path",
|
||||
}
|
||||
return manifests
|
||||
}
|
148
cmd/config/set_manifest.go
Normal file
148
cmd/config/set_manifest.go
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
)
|
||||
|
||||
const (
|
||||
setManifestsLong = `
|
||||
Create or modify a manifests in the airshipctl config file.
|
||||
`
|
||||
|
||||
setManifestsExample = `
|
||||
# Create a new manifest
|
||||
airshipctl config set-manifest exampleManifest \
|
||||
--repo exampleRepo \
|
||||
--url https://github.com/site \
|
||||
--branch master \
|
||||
--primary \
|
||||
--sub-path exampleSubpath \
|
||||
--target-path exampleTargetpath
|
||||
|
||||
# Change the primary repo for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--repo exampleRepo \
|
||||
--primary
|
||||
|
||||
# Change the sub-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--sub-path treasuremap/manifests/e2e
|
||||
|
||||
# Change the target-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--target-path /tmp/e2e
|
||||
`
|
||||
)
|
||||
|
||||
// NewSetManifestCommand creates a command for creating and modifying manifests
|
||||
// in the airshipctl config file.
|
||||
func NewSetManifestCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command {
|
||||
o := &config.ManifestOptions{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "set-manifest NAME",
|
||||
Short: "Manage manifests in airship config",
|
||||
Long: setManifestsLong[1:],
|
||||
Example: setManifestsExample,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
o.Name = args[0]
|
||||
modified, err := config.RunSetManifest(o, rootSettings.Config, true)
|
||||
// Check if URL flag is passed with empty value
|
||||
if cmd.Flags().Changed("url") && o.URL == "" {
|
||||
log.Fatal("Repository URL cannot be empty.")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if modified {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "Manifest %q modified.\n", o.Name)
|
||||
} else {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "Manifest %q created.\n", o.Name)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
addSetManifestFlags(o, cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func addSetManifestFlags(o *config.ManifestOptions, cmd *cobra.Command) {
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.StringVar(
|
||||
&o.RepoName,
|
||||
"repo",
|
||||
"",
|
||||
"the name of the repository to be associated with this manifest")
|
||||
|
||||
flags.StringVar(
|
||||
&o.URL,
|
||||
"url",
|
||||
"",
|
||||
"the repository url to be associated with this manifest")
|
||||
|
||||
flags.StringVar(
|
||||
&o.Branch,
|
||||
"branch",
|
||||
"",
|
||||
"the branch to be associated with repository in this manifest")
|
||||
|
||||
flags.StringVar(
|
||||
&o.CommitHash,
|
||||
"commithash",
|
||||
"",
|
||||
"the commit hash to be associated with repository in this manifest")
|
||||
|
||||
flags.StringVar(
|
||||
&o.Tag,
|
||||
"tag",
|
||||
"",
|
||||
"the tag to be associated with repository in this manifest")
|
||||
|
||||
flags.BoolVar(
|
||||
&o.Force,
|
||||
"force",
|
||||
false,
|
||||
"if set, enable force checkout in repository with this manifest")
|
||||
|
||||
flags.BoolVar(
|
||||
&o.IsPrimary,
|
||||
"primary",
|
||||
false,
|
||||
"if set, enable this repository as primary repository to be used with this manifest")
|
||||
|
||||
flags.StringVar(
|
||||
&o.SubPath,
|
||||
"sub-path",
|
||||
"",
|
||||
"the sub path to be set for this manifest")
|
||||
|
||||
flags.StringVar(
|
||||
&o.TargetPath,
|
||||
"target-path",
|
||||
"",
|
||||
"the target path for to be set for this manifest")
|
||||
}
|
137
cmd/config/set_manifest_test.go
Normal file
137
cmd/config/set_manifest_test.go
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
cmd "opendev.org/airship/airshipctl/cmd/config"
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/environment"
|
||||
"opendev.org/airship/airshipctl/testutil"
|
||||
)
|
||||
|
||||
const (
|
||||
mName = "dummymanifest"
|
||||
mRepoName = "treasuremap"
|
||||
mURL = "https://github.com/airshipit/treasuremap"
|
||||
mBranch = "master"
|
||||
mSubPath = "manifests/test-site"
|
||||
mTargetPath = "/tmp/airship"
|
||||
|
||||
testTargetPath = "/tmp/e2e"
|
||||
)
|
||||
|
||||
type setManifestTest struct {
|
||||
inputConfig *config.Config
|
||||
cmdTest *testutil.CmdTest
|
||||
manifestName string
|
||||
manifestTargetPath string
|
||||
}
|
||||
|
||||
func TestConfigSetManifest(t *testing.T) {
|
||||
cmdTests := []*testutil.CmdTest{
|
||||
{
|
||||
Name: "config-cmd-set-manifest-with-help",
|
||||
CmdLine: "--help",
|
||||
Cmd: cmd.NewSetManifestCommand(nil),
|
||||
},
|
||||
{
|
||||
Name: "config-cmd-set-manifest-too-many-args",
|
||||
CmdLine: "arg1 arg2",
|
||||
Cmd: cmd.NewSetManifestCommand(nil),
|
||||
Error: fmt.Errorf("accepts %d arg(s), received %d", 1, 2),
|
||||
},
|
||||
{
|
||||
Name: "config-cmd-set-manifest-too-few-args",
|
||||
CmdLine: "",
|
||||
Cmd: cmd.NewSetManifestCommand(nil),
|
||||
Error: fmt.Errorf("accepts %d arg(s), received %d", 1, 0),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cmdTests {
|
||||
testutil.RunTest(t, tt)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetManifest(t *testing.T) {
|
||||
given, cleanupGiven := testutil.InitConfig(t)
|
||||
defer cleanupGiven(t)
|
||||
|
||||
tests := []struct {
|
||||
testName string
|
||||
manifestName string
|
||||
flags []string
|
||||
givenConfig *config.Config
|
||||
targetPath string
|
||||
}{
|
||||
{
|
||||
testName: "set-manifest",
|
||||
manifestName: mName,
|
||||
flags: []string{
|
||||
"--repo " + mRepoName,
|
||||
"--url " + mURL,
|
||||
"--branch " + mBranch,
|
||||
"--primary",
|
||||
"--sub-path " + mSubPath,
|
||||
"--target-path " + mTargetPath,
|
||||
},
|
||||
givenConfig: given,
|
||||
targetPath: mTargetPath,
|
||||
},
|
||||
{
|
||||
testName: "modify-manifest",
|
||||
manifestName: mName,
|
||||
flags: []string{
|
||||
"--target-path " + testTargetPath,
|
||||
},
|
||||
givenConfig: given,
|
||||
targetPath: testTargetPath,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
cmd := &testutil.CmdTest{
|
||||
Name: tt.testName,
|
||||
CmdLine: fmt.Sprintf("%s %s", tt.manifestName, strings.Join(tt.flags, " ")),
|
||||
}
|
||||
test := setManifestTest{
|
||||
inputConfig: tt.givenConfig,
|
||||
cmdTest: cmd,
|
||||
manifestName: tt.manifestName,
|
||||
manifestTargetPath: tt.targetPath,
|
||||
}
|
||||
test.run(t)
|
||||
}
|
||||
}
|
||||
|
||||
func (test setManifestTest) run(t *testing.T) {
|
||||
settings := &environment.AirshipCTLSettings{Config: test.inputConfig}
|
||||
test.cmdTest.Cmd = cmd.NewSetManifestCommand(settings)
|
||||
testutil.RunTest(t, test.cmdTest)
|
||||
|
||||
afterRunConf := settings.Config
|
||||
// Find the Manifest Created or Modified
|
||||
afterRunManifest, _ := afterRunConf.Manifests[test.manifestName]
|
||||
require.NotNil(t, afterRunManifest)
|
||||
assert.EqualValues(t, afterRunManifest.TargetPath, test.manifestTargetPath)
|
||||
}
|
@ -8,6 +8,7 @@ Available Commands:
|
||||
get-context Get context information from the airshipctl config
|
||||
get-credential Get user credentials from the airshipctl config
|
||||
get-management-config View a management config or all management configs defined in the airshipctl config
|
||||
get-manifest Get a manifest information from the airshipctl config
|
||||
help Help about any command
|
||||
import Merge information from a kubernetes config file
|
||||
init Generate initial configuration files for airshipctl
|
||||
@ -15,6 +16,7 @@ Available Commands:
|
||||
set-context Manage contexts
|
||||
set-credentials Manage user credentials
|
||||
set-management-config Modify an out-of-band management configuration
|
||||
set-manifest Manage manifests in airship config
|
||||
use-context Switch to a different context
|
||||
|
||||
Flags:
|
||||
|
@ -0,0 +1,41 @@
|
||||
Error: accepts 1 arg(s), received 0
|
||||
Usage:
|
||||
set-manifest NAME [flags]
|
||||
|
||||
Examples:
|
||||
|
||||
# Create a new manifest
|
||||
airshipctl config set-manifest exampleManifest \
|
||||
--repo exampleRepo \
|
||||
--url https://github.com/site \
|
||||
--branch master \
|
||||
--primary \
|
||||
--sub-path exampleSubpath \
|
||||
--target-path exampleTargetpath
|
||||
|
||||
# Change the primary repo for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--repo exampleRepo \
|
||||
--primary
|
||||
|
||||
# Change the sub-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--sub-path treasuremap/manifests/e2e
|
||||
|
||||
# Change the target-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--target-path /tmp/e2e
|
||||
|
||||
|
||||
Flags:
|
||||
--branch string the branch to be associated with repository in this manifest
|
||||
--commithash string the commit hash to be associated with repository in this manifest
|
||||
--force if set, enable force checkout in repository with this manifest
|
||||
-h, --help help for set-manifest
|
||||
--primary if set, enable this repository as primary repository to be used with this manifest
|
||||
--repo string the name of the repository to be associated with this manifest
|
||||
--sub-path string the sub path to be set for this manifest
|
||||
--tag string the tag to be associated with repository in this manifest
|
||||
--target-path string the target path for to be set for this manifest
|
||||
--url string the repository url to be associated with this manifest
|
||||
|
@ -0,0 +1,41 @@
|
||||
Error: accepts 1 arg(s), received 2
|
||||
Usage:
|
||||
set-manifest NAME [flags]
|
||||
|
||||
Examples:
|
||||
|
||||
# Create a new manifest
|
||||
airshipctl config set-manifest exampleManifest \
|
||||
--repo exampleRepo \
|
||||
--url https://github.com/site \
|
||||
--branch master \
|
||||
--primary \
|
||||
--sub-path exampleSubpath \
|
||||
--target-path exampleTargetpath
|
||||
|
||||
# Change the primary repo for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--repo exampleRepo \
|
||||
--primary
|
||||
|
||||
# Change the sub-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--sub-path treasuremap/manifests/e2e
|
||||
|
||||
# Change the target-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--target-path /tmp/e2e
|
||||
|
||||
|
||||
Flags:
|
||||
--branch string the branch to be associated with repository in this manifest
|
||||
--commithash string the commit hash to be associated with repository in this manifest
|
||||
--force if set, enable force checkout in repository with this manifest
|
||||
-h, --help help for set-manifest
|
||||
--primary if set, enable this repository as primary repository to be used with this manifest
|
||||
--repo string the name of the repository to be associated with this manifest
|
||||
--sub-path string the sub path to be set for this manifest
|
||||
--tag string the tag to be associated with repository in this manifest
|
||||
--target-path string the target path for to be set for this manifest
|
||||
--url string the repository url to be associated with this manifest
|
||||
|
41
cmd/config/testdata/TestConfigSetManifestGoldenOutput/config-cmd-set-manifest-with-help.golden
vendored
Normal file
41
cmd/config/testdata/TestConfigSetManifestGoldenOutput/config-cmd-set-manifest-with-help.golden
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
Create or modify a manifests in the airshipctl config file.
|
||||
|
||||
Usage:
|
||||
set-manifest NAME [flags]
|
||||
|
||||
Examples:
|
||||
|
||||
# Create a new manifest
|
||||
airshipctl config set-manifest exampleManifest \
|
||||
--repo exampleRepo \
|
||||
--url https://github.com/site \
|
||||
--branch master \
|
||||
--primary \
|
||||
--sub-path exampleSubpath \
|
||||
--target-path exampleTargetpath
|
||||
|
||||
# Change the primary repo for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--repo exampleRepo \
|
||||
--primary
|
||||
|
||||
# Change the sub-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--sub-path treasuremap/manifests/e2e
|
||||
|
||||
# Change the target-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--target-path /tmp/e2e
|
||||
|
||||
|
||||
Flags:
|
||||
--branch string the branch to be associated with repository in this manifest
|
||||
--commithash string the commit hash to be associated with repository in this manifest
|
||||
--force if set, enable force checkout in repository with this manifest
|
||||
-h, --help help for set-manifest
|
||||
--primary if set, enable this repository as primary repository to be used with this manifest
|
||||
--repo string the name of the repository to be associated with this manifest
|
||||
--sub-path string the sub path to be set for this manifest
|
||||
--tag string the tag to be associated with repository in this manifest
|
||||
--target-path string the target path for to be set for this manifest
|
||||
--url string the repository url to be associated with this manifest
|
12
cmd/config/testdata/TestGetManifestConfigCmdGoldenOutput/get-all-manifests.golden
vendored
Normal file
12
cmd/config/testdata/TestGetManifestConfigCmdGoldenOutput/get-all-manifests.golden
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
primaryRepositoryName: bar_primary_repo
|
||||
subPath: ""
|
||||
targetPath: bar_target_path
|
||||
|
||||
primaryRepositoryName: baz_primary_repo
|
||||
subPath: ""
|
||||
targetPath: baz_target_path
|
||||
|
||||
primaryRepositoryName: foo_primary_repo
|
||||
subPath: ""
|
||||
targetPath: foo_target_path
|
||||
|
4
cmd/config/testdata/TestGetManifestConfigCmdGoldenOutput/get-manifest.golden
vendored
Normal file
4
cmd/config/testdata/TestGetManifestConfigCmdGoldenOutput/get-manifest.golden
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
primaryRepositoryName: foo_primary_repo
|
||||
subPath: ""
|
||||
targetPath: foo_target_path
|
||||
|
19
cmd/config/testdata/TestGetManifestConfigCmdGoldenOutput/missing.golden
vendored
Normal file
19
cmd/config/testdata/TestGetManifestConfigCmdGoldenOutput/missing.golden
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Error: Missing configuration: Manifest with name 'manifestMissing'
|
||||
Usage:
|
||||
get-manifest NAME [flags]
|
||||
|
||||
Aliases:
|
||||
get-manifest, get-manifests
|
||||
|
||||
Examples:
|
||||
|
||||
# List all the manifests airshipctl knows about
|
||||
airshipctl config get-manifests
|
||||
|
||||
# Display a specific manifest
|
||||
airshipctl config get-manifest e2e
|
||||
|
||||
|
||||
Flags:
|
||||
-h, --help help for get-manifest
|
||||
|
1
cmd/config/testdata/TestGetManifestConfigCmdGoldenOutput/no-manifests.golden
vendored
Normal file
1
cmd/config/testdata/TestGetManifestConfigCmdGoldenOutput/no-manifests.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
No Manifest found in the configuration.
|
1
cmd/config/testdata/TestSetManifestGoldenOutput/modify-manifest.golden
vendored
Normal file
1
cmd/config/testdata/TestSetManifestGoldenOutput/modify-manifest.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
Manifest "dummymanifest" modified.
|
1
cmd/config/testdata/TestSetManifestGoldenOutput/set-manifest.golden
vendored
Normal file
1
cmd/config/testdata/TestSetManifestGoldenOutput/set-manifest.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
Manifest "dummymanifest" created.
|
@ -27,11 +27,13 @@ Manage the airshipctl config file
|
||||
* [airshipctl config get-context](airshipctl_config_get-context.md) - Get context information from the airshipctl config
|
||||
* [airshipctl config get-credential](airshipctl_config_get-credential.md) - Get user credentials from the airshipctl config
|
||||
* [airshipctl config get-management-config](airshipctl_config_get-management-config.md) - View a management config or all management configs defined in the airshipctl config
|
||||
* [airshipctl config get-manifest](airshipctl_config_get-manifest.md) - Get a manifest information from the airshipctl config
|
||||
* [airshipctl config import](airshipctl_config_import.md) - Merge information from a kubernetes config file
|
||||
* [airshipctl config init](airshipctl_config_init.md) - Generate initial configuration files for airshipctl
|
||||
* [airshipctl config set-cluster](airshipctl_config_set-cluster.md) - Manage clusters
|
||||
* [airshipctl config set-context](airshipctl_config_set-context.md) - Manage contexts
|
||||
* [airshipctl config set-credentials](airshipctl_config_set-credentials.md) - Manage user credentials
|
||||
* [airshipctl config set-management-config](airshipctl_config_set-management-config.md) - Modify an out-of-band management configuration
|
||||
* [airshipctl config set-manifest](airshipctl_config_set-manifest.md) - Manage manifests in airship config
|
||||
* [airshipctl config use-context](airshipctl_config_use-context.md) - Switch to a different context
|
||||
|
||||
|
43
docs/source/cli/airshipctl_config_get-manifest.md
Normal file
43
docs/source/cli/airshipctl_config_get-manifest.md
Normal file
@ -0,0 +1,43 @@
|
||||
## airshipctl config get-manifest
|
||||
|
||||
Get a manifest information from the airshipctl config
|
||||
|
||||
### Synopsis
|
||||
|
||||
Display a specific manifest information, or all defined manifests if no name is provided.
|
||||
|
||||
|
||||
```
|
||||
airshipctl config get-manifest NAME [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
|
||||
# List all the manifests airshipctl knows about
|
||||
airshipctl config get-manifests
|
||||
|
||||
# Display a specific manifest
|
||||
airshipctl config get-manifest e2e
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for get-manifest
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config")
|
||||
--debug enable verbose output
|
||||
--kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig")
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [airshipctl config](airshipctl_config.md) - Manage the airshipctl config file
|
||||
|
68
docs/source/cli/airshipctl_config_set-manifest.md
Normal file
68
docs/source/cli/airshipctl_config_set-manifest.md
Normal file
@ -0,0 +1,68 @@
|
||||
## airshipctl config set-manifest
|
||||
|
||||
Manage manifests in airship config
|
||||
|
||||
### Synopsis
|
||||
|
||||
Create or modify a manifests in the airshipctl config file.
|
||||
|
||||
|
||||
```
|
||||
airshipctl config set-manifest NAME [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
|
||||
# Create a new manifest
|
||||
airshipctl config set-manifest exampleManifest \
|
||||
--repo exampleRepo \
|
||||
--url https://github.com/site \
|
||||
--branch master \
|
||||
--primary \
|
||||
--sub-path exampleSubpath \
|
||||
--target-path exampleTargetpath
|
||||
|
||||
# Change the primary repo for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--repo exampleRepo \
|
||||
--primary
|
||||
|
||||
# Change the sub-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--sub-path treasuremap/manifests/e2e
|
||||
|
||||
# Change the target-path for manifest
|
||||
airshipctl config set-manifest e2e \
|
||||
--target-path /tmp/e2e
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--branch string the branch to be associated with repository in this manifest
|
||||
--commithash string the commit hash to be associated with repository in this manifest
|
||||
--force if set, enable force checkout in repository with this manifest
|
||||
-h, --help help for set-manifest
|
||||
--primary if set, enable this repository as primary repository to be used with this manifest
|
||||
--repo string the name of the repository to be associated with this manifest
|
||||
--sub-path string the sub path to be set for this manifest
|
||||
--tag string the tag to be associated with repository in this manifest
|
||||
--target-path string the target path for to be set for this manifest
|
||||
--url string the repository url to be associated with this manifest
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config")
|
||||
--debug enable verbose output
|
||||
--kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig")
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [airshipctl config](airshipctl_config.md) - Manage the airshipctl config file
|
||||
|
@ -947,6 +947,112 @@ func (c *Config) CurrentContextBootstrapInfo() (*Bootstrap, error) {
|
||||
return bootstrap, nil
|
||||
}
|
||||
|
||||
// GetManifests returns all of the Manifests associated with the Config sorted by name
|
||||
func (c *Config) GetManifests() []*Manifest {
|
||||
keys := make([]string, 0, len(c.Manifests))
|
||||
for name := range c.Manifests {
|
||||
keys = append(keys, name)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
manifests := make([]*Manifest, 0, len(c.Manifests))
|
||||
for _, name := range keys {
|
||||
manifests = append(manifests, c.Manifests[name])
|
||||
}
|
||||
return manifests
|
||||
}
|
||||
|
||||
// AddManifest creates new Manifest
|
||||
func (c *Config) AddManifest(theManifest *ManifestOptions) *Manifest {
|
||||
nManifest := NewManifest()
|
||||
c.Manifests[theManifest.Name] = nManifest
|
||||
err := c.ModifyManifest(nManifest, theManifest)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return nManifest
|
||||
}
|
||||
|
||||
// ModifyManifest set actual values to manifests
|
||||
func (c *Config) ModifyManifest(manifest *Manifest, theManifest *ManifestOptions) error {
|
||||
if theManifest.IsPrimary {
|
||||
manifest.PrimaryRepositoryName = theManifest.RepoName
|
||||
}
|
||||
if theManifest.SubPath != "" {
|
||||
manifest.SubPath = theManifest.SubPath
|
||||
}
|
||||
if theManifest.TargetPath != "" {
|
||||
manifest.TargetPath = theManifest.TargetPath
|
||||
}
|
||||
// There is no repository details to be updated
|
||||
if theManifest.RepoName == "" {
|
||||
return nil
|
||||
}
|
||||
//when setting an existing repository as primary, verify whether the repository exists
|
||||
//and user is also not passing any repository URL
|
||||
if theManifest.IsPrimary && theManifest.URL == "" && (manifest.Repositories[theManifest.RepoName] == nil) {
|
||||
return ErrRepositoryNotFound{theManifest.RepoName}
|
||||
}
|
||||
repository, exists := manifest.Repositories[theManifest.RepoName]
|
||||
if !exists {
|
||||
_, err := c.AddRepository(manifest, theManifest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err := c.ModifyRepository(repository, theManifest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddRepository creates new Repository
|
||||
func (c *Config) AddRepository(manifest *Manifest, theManifest *ManifestOptions) (*Repository, error) {
|
||||
nRepository := NewRepository()
|
||||
manifest.Repositories[theManifest.RepoName] = nRepository
|
||||
err := c.ModifyRepository(nRepository, theManifest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nRepository, nil
|
||||
}
|
||||
|
||||
// ModifyRepository set actual values to repository
|
||||
func (c *Config) ModifyRepository(repository *Repository, theManifest *ManifestOptions) error {
|
||||
if theManifest.URL != "" {
|
||||
repository.URLString = theManifest.URL
|
||||
}
|
||||
if theManifest.Branch != "" {
|
||||
repository.CheckoutOptions.Branch = theManifest.Branch
|
||||
}
|
||||
if theManifest.CommitHash != "" {
|
||||
repository.CheckoutOptions.CommitHash = theManifest.CommitHash
|
||||
}
|
||||
if theManifest.Tag != "" {
|
||||
repository.CheckoutOptions.Tag = theManifest.Tag
|
||||
}
|
||||
if theManifest.Force {
|
||||
repository.CheckoutOptions.ForceCheckout = theManifest.Force
|
||||
}
|
||||
possibleValues := [3]string{repository.CheckoutOptions.CommitHash,
|
||||
repository.CheckoutOptions.Branch, repository.CheckoutOptions.Tag}
|
||||
var count int
|
||||
for _, val := range possibleValues {
|
||||
if val != "" {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count > 1 {
|
||||
return ErrMutuallyExclusiveCheckout{}
|
||||
}
|
||||
if count == 0 {
|
||||
return ErrMissingRepoCheckoutOptions{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CurrentContextManagementConfig returns the management options for the current context
|
||||
func (c *Config) CurrentContextManagementConfig() (*ManagementConfiguration, error) {
|
||||
currentCluster, err := c.CurrentContextCluster()
|
||||
|
@ -165,3 +165,35 @@ func RunUseContext(desiredContext string, airconfig *Config) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunSetManifest validates the given command line options and invokes AddManifest/ModifyManifest
|
||||
func RunSetManifest(o *ManifestOptions, airconfig *Config, writeToStorage bool) (bool, error) {
|
||||
modified := false
|
||||
err := o.Validate()
|
||||
if err != nil {
|
||||
return modified, err
|
||||
}
|
||||
|
||||
manifest, exists := airconfig.Manifests[o.Name]
|
||||
if !exists {
|
||||
// manifest didn't exist, create it
|
||||
// ignoring the returned added manifest
|
||||
airconfig.AddManifest(o)
|
||||
} else {
|
||||
// manifest exists, lets update
|
||||
err = airconfig.ModifyManifest(manifest, o)
|
||||
if err != nil {
|
||||
return modified, err
|
||||
}
|
||||
modified = true
|
||||
}
|
||||
// Update configuration file just in time persistence approach
|
||||
if writeToStorage {
|
||||
if err := airconfig.PersistConfig(); err != nil {
|
||||
// Error that it didnt persist the changes
|
||||
return modified, ErrConfigFailed{}
|
||||
}
|
||||
}
|
||||
|
||||
return modified, nil
|
||||
}
|
||||
|
@ -117,3 +117,26 @@ func TestRunUseContext(t *testing.T) {
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRunSetManifest(t *testing.T) {
|
||||
t.Run("testAddManifest", func(t *testing.T) {
|
||||
conf := testutil.DummyConfig()
|
||||
dummyManifestOptions := testutil.DummyManifestOptions()
|
||||
dummyManifestOptions.Name = "test_manifest"
|
||||
|
||||
modified, err := config.RunSetManifest(dummyManifestOptions, conf, false)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, modified)
|
||||
})
|
||||
|
||||
t.Run("testModifyManifest", func(t *testing.T) {
|
||||
conf := testutil.DummyConfig()
|
||||
dummyManifestOptions := testutil.DummyManifestOptions()
|
||||
dummyManifestOptions.TargetPath = "/tmp/default"
|
||||
|
||||
modified, err := config.RunSetManifest(dummyManifestOptions, conf, false)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, modified)
|
||||
assert.Equal(t, "/tmp/default", conf.Manifests["dummy_manifest"].TargetPath)
|
||||
})
|
||||
}
|
||||
|
@ -748,3 +748,13 @@ func TestManagementConfigurationByNameDoesNotExist(t *testing.T) {
|
||||
_, err := conf.GetManagementConfiguration(fmt.Sprintf("%s-test", config.AirshipDefaultContext))
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestGetManifests(t *testing.T) {
|
||||
conf, cleanup := testutil.InitConfig(t)
|
||||
defer cleanup(t)
|
||||
|
||||
manifests := conf.GetManifests()
|
||||
require.NotNil(t, manifests)
|
||||
|
||||
assert.EqualValues(t, manifests[0].PrimaryRepositoryName, "primary")
|
||||
}
|
||||
|
@ -65,3 +65,13 @@ const (
|
||||
DefaultSystemActionRetries = 30
|
||||
DefaultSystemRebootDelay = 30
|
||||
)
|
||||
|
||||
// Default Value for manifest
|
||||
const (
|
||||
// DefaultTestPrimaryRepo holds default repo name
|
||||
DefaultTestPrimaryRepo = "primary"
|
||||
// DefaultTargetPath holds default target path
|
||||
DefaultTargetPath = "/tmp/default"
|
||||
// DefaultSubPath holds default sub path
|
||||
DefaultSubPath = "manifest/default"
|
||||
)
|
||||
|
@ -70,6 +70,43 @@ func (e ErrMutuallyExclusiveCheckout) Error() string {
|
||||
return "Checkout mutually exclusive, use either: commit-hash, branch or tag."
|
||||
}
|
||||
|
||||
// ErrRepositoryNotFound is returned if repository is empty
|
||||
// when using in set-manifest
|
||||
type ErrRepositoryNotFound struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (e ErrRepositoryNotFound) Error() string {
|
||||
return fmt.Sprintf("Repository %q not found.", e.Name)
|
||||
}
|
||||
|
||||
// ErrMissingRepositoryName is returned if repository name is empty
|
||||
// when using in set-manifest
|
||||
type ErrMissingRepositoryName struct {
|
||||
}
|
||||
|
||||
func (e ErrMissingRepositoryName) Error() string {
|
||||
return "Missing repository name."
|
||||
}
|
||||
|
||||
// ErrMissingRepoURL is returned if repository is empty
|
||||
// when using --primary in set-manifest
|
||||
type ErrMissingRepoURL struct {
|
||||
}
|
||||
|
||||
func (e ErrMissingRepoURL) Error() string {
|
||||
return "A valid URL should be specified."
|
||||
}
|
||||
|
||||
// ErrMissingRepoCheckoutOptions is returned if repository checkout
|
||||
// options is empty in set-manifest
|
||||
type ErrMissingRepoCheckoutOptions struct {
|
||||
}
|
||||
|
||||
func (e ErrMissingRepoCheckoutOptions) Error() string {
|
||||
return "Missing repository checkout options."
|
||||
}
|
||||
|
||||
// ErrBootstrapInfoNotFound returned if bootstrap
|
||||
// information is not found for cluster
|
||||
type ErrBootstrapInfoNotFound struct {
|
||||
|
@ -19,6 +19,8 @@ package config
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/errors"
|
||||
)
|
||||
|
||||
// AuthInfoOptions holds all configurable options for
|
||||
@ -55,6 +57,21 @@ type ClusterOptions struct {
|
||||
EmbedCAData bool
|
||||
}
|
||||
|
||||
// ManifestOptions holds all configurable options for manifest configuration
|
||||
type ManifestOptions struct {
|
||||
Name string
|
||||
RepoName string
|
||||
URL string
|
||||
Branch string
|
||||
CommitHash string
|
||||
Tag string
|
||||
RemoteRef string
|
||||
Force bool
|
||||
IsPrimary bool
|
||||
SubPath string
|
||||
TargetPath string
|
||||
}
|
||||
|
||||
// TODO(howell): The following functions are tightly coupled with flags passed
|
||||
// on the command line. We should find a way to remove this coupling, since it
|
||||
// is possible to create (and validate) these objects without using the command
|
||||
@ -152,3 +169,28 @@ func checkExists(flagName, path string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate checks for the possible manifest option values and returns
|
||||
// Error when invalid value or incompatible choice of values given
|
||||
func (o *ManifestOptions) Validate() error {
|
||||
if o.Name == "" {
|
||||
return fmt.Errorf("you must specify a non-empty Manifest name")
|
||||
}
|
||||
if o.RemoteRef != "" {
|
||||
return fmt.Errorf("Repository checkout by RemoteRef is not yet implemented\n%w", errors.ErrNotImplemented{})
|
||||
}
|
||||
if o.IsPrimary && o.RepoName == "" {
|
||||
return ErrMissingRepositoryName{}
|
||||
}
|
||||
possibleValues := [3]string{o.CommitHash, o.Branch, o.Tag}
|
||||
var count int
|
||||
for _, val := range possibleValues {
|
||||
if val != "" {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count > 1 {
|
||||
return ErrMutuallyExclusiveCheckout{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -20,11 +20,6 @@ import (
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultTestPrimaryRepo holds default repo name
|
||||
DefaultTestPrimaryRepo = "primary"
|
||||
)
|
||||
|
||||
// NewConfig returns a newly initialized Config object
|
||||
func NewConfig() *Config {
|
||||
return &Config{
|
||||
@ -95,13 +90,17 @@ func NewCluster() *Cluster {
|
||||
func NewManifest() *Manifest {
|
||||
return &Manifest{
|
||||
PrimaryRepositoryName: DefaultTestPrimaryRepo,
|
||||
TargetPath: DefaultTargetPath,
|
||||
SubPath: DefaultSubPath,
|
||||
Repositories: map[string]*Repository{DefaultTestPrimaryRepo: NewRepository()},
|
||||
}
|
||||
}
|
||||
|
||||
// NewRepository is a convenience function that returns a new Repository
|
||||
func NewRepository() *Repository {
|
||||
return &Repository{}
|
||||
return &Repository{
|
||||
CheckoutOptions: &RepoCheckout{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewAuthInfo is a convenience function that returns a new AuthInfo
|
||||
|
@ -264,6 +264,21 @@ func DummyManagementConfiguration() *config.ManagementConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
// DummyManifestOptions creates ManifestOptions config object
|
||||
// for unit testing
|
||||
func DummyManifestOptions() *config.ManifestOptions {
|
||||
return &config.ManifestOptions{
|
||||
Name: "dummy_manifest",
|
||||
SubPath: "manifests/dummy_site",
|
||||
TargetPath: "/tmp/dummy_site",
|
||||
IsPrimary: true,
|
||||
RepoName: "dummy_repo",
|
||||
URL: "https://github.com/treasuremap/dummy_site",
|
||||
Branch: "master",
|
||||
Force: true,
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
testConfigYAML = `apiVersion: airshipit.org/v1alpha1
|
||||
bootstrapInfo:
|
||||
|
Loading…
Reference in New Issue
Block a user