Skip to content

Commit

Permalink
fix: refactored deploymentType and root commands, renamed config stru…
Browse files Browse the repository at this point in the history
…ct and moved it out of parse function
  • Loading branch information
dlactin committed Jan 17, 2025
1 parent dc3e398 commit 539b57f
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 75 deletions.
83 changes: 51 additions & 32 deletions tenants/cmd/deploymentType.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,61 @@ import (
"github.com/spf13/cobra"
)

// deploymentTypeCmd represents the deploymentType command
var deploymentTypeCmd = &cobra.Command{
Use: "deploymentType",
Short: "Parse tenant files directory for deployment type",
Long: `Parse a local tenant files directory for deployment type
Example:
./tenants deploymentType -d ../../global-platform-admin/tenants`,
RunE: func(cmd *cobra.Command, args []string) error {
return runAnalysis(cmd)
},
type DeploymentTypeOptions struct {
TenantDirectory string
OutputFile string
Format string
}

func init() {
rootCmd.AddCommand(deploymentTypeCmd)
func newDeploymentTypeCmd() *cobra.Command {
opts := new(DeploymentTypeOptions)

deploymentTypeCmd.Flags().StringP("directory", "d", "../tenants", "Path to the tenants directory containing YAML files")
deploymentTypeCmd.Flags().StringP("output", "o", "deployment_type.csv", "Output file")
deploymentTypeCmd.Flags().StringP("format", "f", "csv", "Output format: csv or json")
}
cmd := &cobra.Command{
Use: "deploymentType",
Short: "Parse tenant files directory for deployment type",
Long: `Parse a local tenant files directory for deployment type
Example:
./tenants deploymentType -d ../../global-platform-admin/tenants`,
PreRunE: func(cmd *cobra.Command, args []string) error {
// Bind the directory flag
directory, err := cmd.Flags().GetString("directory")
if err != nil {
return fmt.Errorf("failed to get directory flag: %w", err)
}
opts.TenantDirectory = directory

func runAnalysis(cmd *cobra.Command) error {
directory, err := cmd.Flags().GetString("directory")
if err != nil {
return fmt.Errorf("failed to get directory flag: %v", err)
}
// Bind the output file flag
outputFile, err := cmd.Flags().GetString("output")
if err != nil {
return fmt.Errorf("failed to get output flag: %w", err)
}
opts.OutputFile = outputFile

outputFile, err := cmd.Flags().GetString("output")
if err != nil {
return fmt.Errorf("failed to get output flag: %v", err)
}
// Bind the format flag
format, err := cmd.Flags().GetString("format")
if err != nil {
return fmt.Errorf("failed to get format flag: %w", err)
}
opts.Format = format

format, err := cmd.Flags().GetString("format")
if err != nil {
return fmt.Errorf("failed to get format flag: %v", err)
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return runAnalysis(opts)
},
}

cmd.Flags().StringP("output", "o", "deployment_type.csv", "Output file")
cmd.Flags().StringP("format", "f", "csv", "Output format: csv or json")

return cmd
}

func runAnalysis(opts *DeploymentTypeOptions) error {
directory := opts.TenantDirectory
outputFile := opts.OutputFile
format := opts.Format

files, err := io.GetYamlFiles(directory)
if err != nil {
return fmt.Errorf("error fetching YAML files: %v", err)
Expand All @@ -64,14 +83,14 @@ func runAnalysis(cmd *cobra.Command) error {
fmt.Printf("Checking tenant: %s\n", fileName)
content, err := os.ReadFile(file)
if err != nil {
fmt.Printf("Error reading tenant file %s: %v\n", fileName, err)
fmt.Printf("Skipping tenant file %s due to an error: %v\n", fileName, err)
continue
}
deploymentType, migrationStatus := io.ParseDeploymentTypeAndMigration(string(content))
results = append(results, map[string]string{
"Tenant Name": fileName,
"Deployment Type": deploymentType,
"Migration Status": migrationStatus,
"TenantName": fileName,
"DeploymentType": deploymentType,
"MigrationStatus": migrationStatus,
})

if deploymentType == "argocd" {
Expand Down
33 changes: 23 additions & 10 deletions tenants/cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,40 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "tenants",
Short: "CLI app for parsing GCPv2 tenant files for cataloguing",
Long: "CLI app for parsing GCPv2 tenant files for cataloguing",
// newRootCmd creates a new base command for the metrics CLI app
func newRootCmd() *cobra.Command {
rootCmd := &cobra.Command{
Use: "tenants",
Short: "CLI app for parsing GCPv2 tenant files for cataloguing",
Long: "CLI app for parsing GCPv2 tenant files for cataloguing",
}

rootCmd.PersistentFlags().StringP("directory", "d", "", "Path to the tenants directory containing YAML files")
rootCmd.MarkPersistentFlagRequired("directory")

rootCmd.AddCommand(newDeploymentTypeCmd())

return rootCmd
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
// Execute the CLI application and write errors to os.Stderr
func Execute() {
err := rootCmd.Execute()
if err != nil {
rootCmd := newRootCmd()
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}

func init() {
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
// New in cobra v1.8.0. See https://github.com/spf13/cobra/pull/2044
// Run all PersistentPreRunE hooks, so we don't have to repeat factory
// configuration or CLI flags parsing in sub commands.
cobra.EnableTraverseRunHooks = true
}
53 changes: 30 additions & 23 deletions tenants/internal/io/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@ import (
"gopkg.in/yaml.v2"
)

type Tenant struct {
Globals struct {
Deployment struct {
Type string `yaml:"type"`
} `yaml:"deployment"`
} `yaml:"globals"`
Realms struct {
Nonprod struct {
Deployment struct {
Type string `yaml:"type"`
} `yaml:"deployment"`
} `yaml:"nonprod"`
Prod struct {
Deployment struct {
Type string `yaml:"type"`
} `yaml:"deployment"`
} `yaml:"prod"`
} `yaml:"realms"`
}

func GetYamlFiles(directory string) ([]string, error) {
var files []string
err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
Expand All @@ -29,27 +49,9 @@ func GetYamlFiles(directory string) ([]string, error) {
}

func ParseDeploymentTypeAndMigration(fileContent string) (string, string) {
var config struct {
Globals struct {
Deployment struct {
Type string `yaml:"type"`
} `yaml:"deployment"`
} `yaml:"globals"`
Realms struct {
Nonprod struct {
Deployment struct {
Type string `yaml:"type"`
} `yaml:"deployment"`
} `yaml:"nonprod"`
Prod struct {
Deployment struct {
Type string `yaml:"type"`
} `yaml:"deployment"`
} `yaml:"prod"`
} `yaml:"realms"`
}
var tenant Tenant

err := yaml.Unmarshal([]byte(fileContent), &config)
err := yaml.Unmarshal([]byte(fileContent), &tenant)
if err != nil {
fmt.Printf("Error parsing YAML content: %v\n", err)
return "Error", "Error"
Expand All @@ -58,17 +60,17 @@ func ParseDeploymentTypeAndMigration(fileContent string) (string, string) {
deploymentTypes := make(map[string]bool)

// Collect deployment types
globalType := strings.Trim(config.Globals.Deployment.Type, "\" ")
globalType := strings.Trim(tenant.Globals.Deployment.Type, "\" ")
if globalType != "" {
deploymentTypes[globalType] = true
}

nonprodType := strings.Trim(config.Realms.Nonprod.Deployment.Type, "\" ")
nonprodType := strings.Trim(tenant.Realms.Nonprod.Deployment.Type, "\" ")
if nonprodType != "" {
deploymentTypes[nonprodType] = true
}

prodType := strings.Trim(config.Realms.Prod.Deployment.Type, "\" ")
prodType := strings.Trim(tenant.Realms.Prod.Deployment.Type, "\" ")
if prodType != "" {
deploymentTypes[prodType] = true
}
Expand All @@ -88,6 +90,11 @@ func ParseDeploymentTypeAndMigration(fileContent string) (string, string) {
migrationStatus = "unknown"
}

/*
This is being used to track live and complete migrations to ArgoCD
On average these migrations have taken less than a week to complete
and the detailed progress is tracked by migrationStatus
*/
deploymentType := ""
if hasArgocd {
deploymentType = "argocd"
Expand Down
20 changes: 10 additions & 10 deletions tenants/internal/io/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func WriteCSV(outputFile string, results []map[string]string) error {
defer csvWriter.Flush()

// Define the explicit order of fields
headers := []string{"Tenant Name", "Deployment Type", "Migration Status"}
headers := []string{"TenantName", "DeploymentType", "MigrationStatus"}
err = csvWriter.Write(headers)
if err != nil {
fmt.Printf("Error writing CSV Headers")
Expand All @@ -27,9 +27,9 @@ func WriteCSV(outputFile string, results []map[string]string) error {
// Write rows
for _, result := range results {
row := []string{
result["Tenant Name"],
result["Deployment Type"],
result["Migration Status"],
result["TenantName"],
result["DeploymentType"],
result["MigrationStatus"],
}
err = csvWriter.Write(row)
if err != nil {
Expand All @@ -41,9 +41,9 @@ func WriteCSV(outputFile string, results []map[string]string) error {
}

type Result struct {
TenantName string `json:"Tenant Name"`
DeploymentType string `json:"Deployment Type"`
MigrationStatus string `json:"Migration Status"`
TenantName string
DeploymentType string
MigrationStatus string
}

func WriteJSON(outputFile string, results []map[string]string) error {
Expand All @@ -57,9 +57,9 @@ func WriteJSON(outputFile string, results []map[string]string) error {
structResults := []Result{}
for _, result := range results {
structResults = append(structResults, Result{
TenantName: result["Tenant Name"],
DeploymentType: result["Deployment Type"],
MigrationStatus: result["Migration Status"],
TenantName: result["TenantName"],
DeploymentType: result["DeploymentType"],
MigrationStatus: result["MigrationStatus"],
})
}

Expand Down

0 comments on commit 539b57f

Please sign in to comment.