Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding CLI for the migration tool #154

Merged
merged 5 commits into from
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions kubernetes/corefile-tool/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Corefile
corefile-tool
*.yaml
62 changes: 62 additions & 0 deletions kubernetes/corefile-tool/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## Corefile-tool

Corefile-tool is a simple command line tool which helps you to evaluate and migrate your CoreDNS Corefile Configuration.
It is based on the [CoreDNS migration tool library](https://github.com/coredns/deployment/tree/master/kubernetes/migration).

## Usage

Use the following syntax to run the `corefile-tool` command:

`corefile-tool [command] [flags]`

where `command`, `flags` are:

- `command`: The operation you want to perform.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to define what the valid commands are. I think these are in the "Operations" section, but the terminology is not consistent command/operation, so it's confusing.

- `flags` : Specifies flags required to carry out the operations.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to define what the valid flags are per command.



### Operations

The following operations are supported:
- `default`: Default returns true if the Corefile is the default for a that version of Kubernetes.
If the Kubernetes version is omitted, returns true if the Corefile is the default for any version.

- `deprecated` : Deprecated returns a list of deprecated plugins or directives present in the Corefile.
- `migrate` : Migrate your CoreDNS corefile.
- `removed` : Removed returns a list of removed plugins or directives present in the Corefile.
- `unsupported` : Unsupported returns a list of plugins that are not recognized/supported by the migration tool (but may still be valid in CoreDNS).
- `validversions` : Shows valid versions of CoreDNS.


### Examples

The following examples will help you understand the basic usage of the migration tool.

```bash
# See if the Corefile is the default in CoreDNS v1.4.0.
corefile-tool default --k8sversion 1.4.0 --corefile /path/to/Corefile
```

```bash
# See deprecated plugins CoreDNS from v1.4.0 to v1.5.0.
corefile-tool deprecated --from 1.4.0 --to 1.5.0 --corefile /path/to/Corefile
```

```bash
# See unsupported plugins CoreDNS from v1.4.0 to v1.5.0.
corefile-tool unsupported --from 1.4.0 --to 1.5.0 --corefile /path/to/Corefile
```

```bash
# See removed plugins CoreDNS from v1.4.0 to v1.5.0.
corefile-tool removed --from 1.4.0 --to 1.5.0 --corefile /path/to/Corefile
```

```bash
# Migrate CoreDNS from v1.4.0 to v1.5.0 and handle deprecations .
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should explain what "handle deprecations" means.

corefile-tool migrate --from 1.4.0 --to 1.5.0 --corefile /path/to/Corefile --deprecations true

# Migrate CoreDNS from v1.2.2 to v1.3.1 and do not handle deprecations .
corefile-tool migrate --from 1.2.2 --to 1.3.1 --corefile /path/to/Corefile --deprecations false
```

47 changes: 47 additions & 0 deletions kubernetes/corefile-tool/cmd/default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cmd

import (
"fmt"

"github.com/coredns/deployment/kubernetes/migration"

"github.com/spf13/cobra"
)

// NewDefaultCmd represents the default command
func NewDefaultCmd() *cobra.Command {
defaultCmd := &cobra.Command{
Use: "default",
Short: "default returns true if the Corefile is the default for a that version of Kubernetes. If the Kubernetes version is omitted, returns true if the Corefile is the default for any version.",
Example: `# See if the Corefile is the default in CoreDNS v1.4.0.
corefile-tool default --k8sversion 1.4.0 --corefile /path/to/Corefile`,
RunE: func(cmd *cobra.Command, args []string) error {
k8sversion, _ := cmd.Flags().GetString("k8sversion")
corefile, _ := cmd.Flags().GetString("corefile")

isDefault, err := defaultCorefileFromPath(k8sversion, corefile)
if err != nil {
return fmt.Errorf("error while checking if the Corefile is the default: %v \n", err)
}
fmt.Println(isDefault)

return nil
},
}
defaultCmd.Flags().String("k8sversion", "", "The Kuberenetes version for which you are checking the default.")
defaultCmd.Flags().String("corefile", "", "Required: The path where your Corefile is located.")
defaultCmd.MarkFlagRequired("corefile")

return defaultCmd
}

// defaultCorefileFromPath takes the path where the Corefile is located and checks
// if the Corefile is the default for that version of Kubernetes.
func defaultCorefileFromPath(k8sVersion, corefilePath string) (bool, error) {
fileBytes, err := getCorefileFromPath(corefilePath)
if err != nil {
return false, err
}
corefileStr := string(fileBytes)
return migration.Default(k8sVersion, corefileStr), nil
}
51 changes: 51 additions & 0 deletions kubernetes/corefile-tool/cmd/deprecated.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package cmd

import (
"fmt"

"github.com/coredns/deployment/kubernetes/migration"

"github.com/spf13/cobra"
)

// NewDeprecatedCmd represents the deprecated command
func NewDeprecatedCmd() *cobra.Command {
deprecatedCmd := &cobra.Command{
Use: "deprecated",
Short: "Deprecated returns a list of deprecated plugins or directives present in the Corefile.",
Example: `# See deprecated plugins CoreDNS from v1.4.0 to v1.5.0.
corefile-tool deprecated --from 1.4.0 --to 1.5.0 --corefile /path/to/Corefile`,
RunE: func(cmd *cobra.Command, args []string) error {
from, _ := cmd.Flags().GetString("from")
to, _ := cmd.Flags().GetString("to")
corefile, _ := cmd.Flags().GetString("corefile")
deprecated, err := deprecatedCorefileFromPath(from, to, corefile)
if err != nil {
return fmt.Errorf("error while listing deprecated plugins: %v \n", err)
}
for _, dep := range deprecated {
fmt.Println(dep.ToString())
}
return nil
},
}
deprecatedCmd.Flags().String("from", "", "Required: The version you are migrating from. ")
deprecatedCmd.MarkFlagRequired("from")
deprecatedCmd.Flags().String("to", "", "Required: The version you are migrating to.")
deprecatedCmd.MarkFlagRequired("to")
deprecatedCmd.Flags().String("corefile", "", "Required: The path where your Corefile is located.")
deprecatedCmd.MarkFlagRequired("corefile")

return deprecatedCmd
}

// deprecatedCorefileFromPath takes the path where the Corefile is located and returns the deprecated plugins or directives
// present in the Corefile.
func deprecatedCorefileFromPath(fromCoreDNSVersion, toCoreDNSVersion, corefilePath string) ([]migration.Notice, error) {
fileBytes, err := getCorefileFromPath(corefilePath)
if err != nil {
return nil, err
}
corefileStr := string(fileBytes)
return migration.Deprecated(fromCoreDNSVersion, toCoreDNSVersion, corefileStr)
}
56 changes: 56 additions & 0 deletions kubernetes/corefile-tool/cmd/migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package cmd

import (
"fmt"

"github.com/coredns/deployment/kubernetes/migration"

"github.com/spf13/cobra"
)

// NewMigrateCmd represents the migrate command
func NewMigrateCmd() *cobra.Command {
var migrateCmd = &cobra.Command{
Use: "migrate",
Short: "Migrate your CoreDNS corefile",
Example: `# Migrate CoreDNS from v1.4.0 to v1.5.0 and handle deprecations .
corefile-tool migrate --from 1.4.0 --to 1.5.0 --corefile /path/to/Corefile --deprecations true

# Migrate CoreDNS from v1.2.2 to v1.3.1 and do not handle deprecations .
corefile-tool migrate --from 1.2.2 --to 1.3.1 --corefile /path/to/Corefile --deprecations false`,
RunE: func(cmd *cobra.Command, args []string) error {
from, _ := cmd.Flags().GetString("from")
to, _ := cmd.Flags().GetString("to")
corefile, _ := cmd.Flags().GetString("corefile")
deprecations, _ := cmd.Flags().GetBool("deprecations")

migrated, err := migrateCorefileFromPath(from, to, corefile, deprecations)
if err != nil {
return fmt.Errorf("error while migration: %v \n", err)
}
fmt.Println(migrated)
return nil
},
}
migrateCmd.Flags().String("from", "", "Required: The version you are migrating from. ")
migrateCmd.MarkFlagRequired("from")
migrateCmd.Flags().String("to", "", "Required: The version you are migrating to.")
migrateCmd.MarkFlagRequired("to")
migrateCmd.Flags().String("corefile", "", "Required: The path where your Corefile is located.")
migrateCmd.MarkFlagRequired("corefile")
migrateCmd.Flags().Bool("deprecations", false, "Required: Specify whether you want to handle plugin deprecations. [True | False] ")
migrateCmd.MarkFlagRequired("deprecations")

return migrateCmd
}

// migrateCorefileFromPath takes the path where the Corefile is located and returns the deprecated plugins or directives
// present in the Corefile.
func migrateCorefileFromPath(fromCoreDNSVersion, toCoreDNSVersion, corefilePath string, deprecations bool) (string, error) {
fileBytes, err := getCorefileFromPath(corefilePath)
if err != nil {
return "", err
}
corefileStr := string(fileBytes)
return migration.Migrate(fromCoreDNSVersion, toCoreDNSVersion, corefileStr, deprecations)
}
52 changes: 52 additions & 0 deletions kubernetes/corefile-tool/cmd/removed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmd

import (
"fmt"

"github.com/coredns/deployment/kubernetes/migration"

"github.com/spf13/cobra"
)

// NewRemovedCmd represents the removed command
func NewRemovedCmd() *cobra.Command {
removedCmd := &cobra.Command{
Use: "removed",
Short: "Removed returns a list of removed plugins or directives present in the Corefile.",
Example: `# See removed plugins CoreDNS from v1.4.0 to v1.5.0.
corefile-tool removed --from 1.4.0 --to 1.5.0 --corefile /path/to/Corefile`,
RunE: func(cmd *cobra.Command, args []string) error {
from, _ := cmd.Flags().GetString("from")
to, _ := cmd.Flags().GetString("to")
corefile, _ := cmd.Flags().GetString("corefile")
removed, err := removedCorefileFromPath(from, to, corefile)
if err != nil {
return fmt.Errorf("error while listing deprecated plugins: %v \n", err)
}
for _, rem := range removed {
fmt.Println(rem.ToString())
}
return nil
},

}
removedCmd.Flags().String("from", "", "Required: The version you are migrating from. ")
removedCmd.MarkFlagRequired("from")
removedCmd.Flags().String("to", "", "Required: The version you are migrating to.")
removedCmd.MarkFlagRequired("to")
removedCmd.Flags().String("corefile", "", "Required: The path where your Corefile is located.")
removedCmd.MarkFlagRequired("corefile")

return removedCmd
}

// removedCorefileFromPath takes the path where the Corefile is located and returns the plugins or directives
// that have been removed.
func removedCorefileFromPath(fromCoreDNSVersion, toCoreDNSVersion, corefilePath string) ([]migration.Notice, error) {
fileBytes, err := getCorefileFromPath(corefilePath)
if err != nil {
return nil, err
}
corefileStr := string(fileBytes)
return migration.Removed(fromCoreDNSVersion, toCoreDNSVersion, corefileStr)
}
58 changes: 58 additions & 0 deletions kubernetes/corefile-tool/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package cmd

import (
"fmt"
"io/ioutil"
"os"

"github.com/lithammer/dedent"
"github.com/spf13/cobra"
)

// CorefileTool represents the base command for the corefile-tool.
func CorefileTool() *cobra.Command {
rootCmd := &cobra.Command{
Use: "corefile-tool",
Short: "A brief description of your application",
Long: dedent.Dedent(`

┌──────────────────────────────────────────────────────────┐
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good !

│ CoreDNS Migration Tool │
│ Easily Migrate your Corefile │
│ │
│ Please give us feedback at: │
│ https://github.com/coredns/deployment/issues │
└──────────────────────────────────────────────────────────┘

`),
}
rootCmd.AddCommand(NewRemovedCmd())
rootCmd.AddCommand(NewMigrateCmd())
rootCmd.AddCommand(NewDefaultCmd())
rootCmd.AddCommand(NewDeprecatedCmd())
rootCmd.AddCommand(NewUnsupportedCmd())
rootCmd.AddCommand(NewValidVersionsCmd())

return rootCmd
}

// Execute adds all child commands to the root command and sets flags appropriately.
func Execute() {
if err := CorefileTool().Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

func getCorefileFromPath(corefilePath string) ([]byte, error) {
if _, err := os.Stat(corefilePath); os.IsNotExist(err) {
return nil, err
}

fileBytes, err := ioutil.ReadFile(corefilePath)
if err != nil {
return nil, err
}

return fileBytes, nil
}
52 changes: 52 additions & 0 deletions kubernetes/corefile-tool/cmd/unsupported.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmd

import (
"fmt"

"github.com/coredns/deployment/kubernetes/migration"

"github.com/spf13/cobra"
)

// NewUnsupportedCmd represents the unsupported command
func NewUnsupportedCmd() *cobra.Command {
unsupportedCmd := &cobra.Command{
Use: "unsupported",
Short: "Unsupported returns a list of plugins that are not recognized/supported by the migration tool (but may still be valid in CoreDNS).",
Example: `# See unsupported plugins CoreDNS from v1.4.0 to v1.5.0.
corefile-tool unsupported --from 1.4.0 --to 1.5.0 --corefile /path/to/Corefile`,
RunE: func(cmd *cobra.Command, args []string) error {
from, _ := cmd.Flags().GetString("from")
to, _ := cmd.Flags().GetString("to")
corefile, _ := cmd.Flags().GetString("corefile")
unsupported, err := unsupportedCorefileFromPath(from, to, corefile)
if err != nil {
return fmt.Errorf("error while listing deprecated plugins: %v \n", err)
}
for _, unsup := range unsupported {
fmt.Println(unsup.ToString())
}
return nil
},
}

unsupportedCmd.Flags().String("from", "", "Required: The version you are migrating from. ")
unsupportedCmd.MarkFlagRequired("from")
unsupportedCmd.Flags().String("to", "", "Required: The version you are migrating to.")
unsupportedCmd.MarkFlagRequired("to")
unsupportedCmd.Flags().String("corefile", "", "Required: The path where your Corefile is located.")
unsupportedCmd.MarkFlagRequired("corefile")

return unsupportedCmd
}

// unsupportedCorefileFromPath takes the path where the Corefile is located and returns a list of plugins
// that have been removed.
func unsupportedCorefileFromPath(fromCoreDNSVersion, toCoreDNSVersion, corefilePath string) ([]migration.Notice, error) {
fileBytes, err := getCorefileFromPath(corefilePath)
if err != nil {
return nil, err
}
corefileStr := string(fileBytes)
return migration.Unsupported(fromCoreDNSVersion, toCoreDNSVersion, corefileStr)
}
Loading