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

feat: added site pruning logic #427

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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 .changes/unreleased/Fixed-20241210-120846.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: Fixed
body: Re-added site targeting on plan and apply
time: 2024-12-10T12:08:46.512121798+01:00
2 changes: 1 addition & 1 deletion docs/src/reference/cli/mach-composer_apply.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mach-composer apply [flags]
-h, --help help for apply
--ignore-change-detection Ignore change detection to run even if the components are considered up to date
--ignore-version Skip MACH composer version check
--output-path string Outputs path to store the generated files. (default "deployments")
-o, --output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
Expand Down
3 changes: 1 addition & 2 deletions docs/src/reference/cli/mach-composer_components.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ mach-composer components [flags]
-f, --file string YAML file to parse. (default "main.yml")
-h, --help help for components
--ignore-version Skip MACH composer version check
--output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
-o, --output-path string Outputs path to store the generated files. (default "deployments")
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
```
Expand Down
3 changes: 1 addition & 2 deletions docs/src/reference/cli/mach-composer_generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ mach-composer generate [flags]
-f, --file string YAML file to parse. (default "main.yml")
-h, --help help for generate
--ignore-version Skip MACH composer version check
--output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
-o, --output-path string Outputs path to store the generated files. (default "deployments")
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
```
Expand Down
3 changes: 1 addition & 2 deletions docs/src/reference/cli/mach-composer_graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ mach-composer graph [flags]
-f, --file string YAML file to parse. (default "main.yml")
-h, --help help for graph
--ignore-version Skip MACH composer version check
--output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
-o, --output-path string Outputs path to store the generated files. (default "deployments")
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
```
Expand Down
2 changes: 1 addition & 1 deletion docs/src/reference/cli/mach-composer_init.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mach-composer init [flags]
-f, --file string YAML file to parse. (default "main.yml")
-h, --help help for init
--ignore-version Skip MACH composer version check
--output-path string Outputs path to store the generated files. (default "deployments")
-o, --output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
Expand Down
2 changes: 1 addition & 1 deletion docs/src/reference/cli/mach-composer_plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mach-composer plan [flags]
--ignore-change-detection Ignore change detection to run even if the components are considered up to date
--ignore-version Skip MACH composer version check
--lock Acquire a lock on the state file before running terraform plan (default true)
--output-path string Outputs path to store the generated files. (default "deployments")
-o, --output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
Expand Down
3 changes: 1 addition & 2 deletions docs/src/reference/cli/mach-composer_show-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ mach-composer show-plan [flags]
--ignore-change-detection Ignore change detection to run even if the components are considered up to date
--ignore-version Skip MACH composer version check
--no-color Disable color output
--output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
-o, --output-path string Outputs path to store the generated files. (default "deployments")
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
```
Expand Down
3 changes: 1 addition & 2 deletions docs/src/reference/cli/mach-composer_sites.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ mach-composer sites [flags]
-f, --file string YAML file to parse. (default "main.yml")
-h, --help help for sites
--ignore-version Skip MACH composer version check
--output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
-o, --output-path string Outputs path to store the generated files. (default "deployments")
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
```
Expand Down
3 changes: 1 addition & 2 deletions docs/src/reference/cli/mach-composer_terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ mach-composer terraform [flags]
-h, --help help for terraform
--ignore-change-detection Ignore change detection to run even if the components are considered up to date. Per default the proxy will ignore change detection (default true)
--ignore-version Skip MACH composer version check
--output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
-o, --output-path string Outputs path to store the generated files. (default "deployments")
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
```
Expand Down
3 changes: 1 addition & 2 deletions docs/src/reference/cli/mach-composer_validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ mach-composer validate [flags]
-f, --file string YAML file to parse. (default "main.yml")
-h, --help help for validate
--ignore-version Skip MACH composer version check
--output-path string Outputs path to store the generated files. (default "deployments")
-s, --site string Site to parse. If not set parse all sites.
-o, --output-path string Outputs path to store the generated files. (default "deployments")
--validation-path string Directory path to store files required for configuration validation. (default "validations")
--var-file string Use a variable file to parse the configuration with.
-w, --workers int The number of workers to use (default 1)
Expand Down
4 changes: 3 additions & 1 deletion internal/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var applyFlags struct {
autoApprove bool
destroy bool
components []string
site string
numWorkers int
ignoreChangeDetection bool
}
Expand All @@ -37,6 +38,7 @@ func init() {
applyCmd.Flags().BoolVarP(&applyFlags.forceInit, "force-init", "", false, "Force terraform initialization. By default mach-composer will reuse existing terraform resources")
applyCmd.Flags().BoolVarP(&applyFlags.autoApprove, "auto-approve", "", false, "Suppress a terraform init for improved speed (not recommended for production usage)")
applyCmd.Flags().BoolVarP(&applyFlags.destroy, "destroy", "", false, "Destroy option is a convenient way to destroy all remote objects managed by this mach config")
applyCmd.Flags().StringVarP(&applyFlags.site, "site", "s", "", "Site to parse. If not set parse all sites.")
applyCmd.Flags().StringArrayVarP(&applyFlags.components, "component", "c", nil, "")
applyCmd.Flags().BoolVarP(&applyFlags.ignoreChangeDetection, "ignore-change-detection", "", false, "Ignore change detection to run even if the components are considered up to date")
}
Expand All @@ -50,7 +52,7 @@ func applyFunc(cmd *cobra.Command, _ []string) error {
defer cfg.Close()
ctx := cmd.Context()

dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath, graph.WithTargetSiteName(applyFlags.site))
if err != nil {
return err
}
Expand Down
8 changes: 1 addition & 7 deletions internal/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (

type CommonFlags struct {
configFile string
siteName string
ignoreVersion bool
outputPath string
varFile string
Expand All @@ -29,20 +28,15 @@ var commonFlags CommonFlags
func registerCommonFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&commonFlags.configFile, "file", "f", "main.yml", "YAML file to parse.")
cmd.Flags().StringVarP(&commonFlags.varFile, "var-file", "", "", "Use a variable file to parse the configuration with.")
cmd.Flags().StringVarP(&commonFlags.siteName, "site", "s", "", "Site to parse. If not set parse all sites.")
cmd.Flags().BoolVarP(&commonFlags.ignoreVersion, "ignore-version", "", false, "Skip MACH composer version check")
cmd.Flags().StringVarP(&commonFlags.outputPath, "output-path", "", "deployments",
cmd.Flags().StringVarP(&commonFlags.outputPath, "output-path", "o", "deployments",
"Outputs path to store the generated files.")
cmd.Flags().IntVarP(&commonFlags.workers, "workers", "w", 1, "The number of workers to use")

_ = cmd.RegisterFlagCompletionFunc("site", AutocompleteSiteName)
}

func preprocessCommonFlags(cmd *cobra.Command) {
if commonFlags.siteName != "" {
log.Warn().Msgf("Site option not implemented")
}

handleError(cmd.MarkFlagFilename("var-file", "yml", "yaml"))
handleError(cmd.MarkFlagFilename("file", "yml", "yaml"))

Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import (
"github.com/mach-composer/mach-composer-cli/internal/runner"
)

var initFlags struct {
site string
}

var initCmd = &cobra.Command{
Use: "init",
Short: "Initialize site directories Terraform files.",
Expand All @@ -28,14 +32,15 @@ var initCmd = &cobra.Command{

func init() {
registerCommonFlags(initCmd)
initCmd.Flags().StringVarP(&initFlags.site, "site", "s", "", "Site to parse. If not set parse all sites.")
}

func initFunc(cmd *cobra.Command, _ []string) error {
cfg := loadConfig(cmd, true)
defer cfg.Close()
ctx := cmd.Context()

dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath, graph.WithTargetSiteName(initFlags.site))
if err != nil {
return err
}
Expand Down
4 changes: 3 additions & 1 deletion internal/cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

var planFlags struct {
forceInit bool
site string
components []string
lock bool
ignoreChangeDetection bool
Expand All @@ -33,6 +34,7 @@ var planCmd = &cobra.Command{
func init() {
registerCommonFlags(planCmd)
planCmd.Flags().BoolVarP(&planFlags.forceInit, "force-init", "", false, "Force terraform initialization. By default mach-composer will reuse existing terraform resources")
planCmd.Flags().StringVarP(&planFlags.site, "site", "s", "", "Site to parse. If not set parse all sites.")
planCmd.Flags().StringArrayVarP(&planFlags.components, "component", "c", nil, "")
planCmd.Flags().BoolVarP(&planFlags.lock, "lock", "", true, "Acquire a lock on the state file before running terraform plan")
planCmd.Flags().BoolVarP(&planFlags.ignoreChangeDetection, "ignore-change-detection", "", false, "Ignore change detection to run even if the components are considered up to date")
Expand All @@ -47,7 +49,7 @@ func planFunc(cmd *cobra.Command, _ []string) error {
defer cfg.Close()
ctx := cmd.Context()

dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath, graph.WithTargetSiteName(planFlags.site))
if err != nil {
return err
}
Expand Down
62 changes: 59 additions & 3 deletions internal/graph/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,45 @@ import (
"github.com/mach-composer/mach-composer-cli/internal/config"
)

type options struct {
siteTarget string
}

type Option func(o *options)

func WithTargetSiteName(site string) Option {
return func(o *options) {
o.siteTarget = site
}
}

// ToDeploymentGraph converts a MachConfig to a Graph ready for deployment.
// This means that all nodes that are not independently deployable are pruned from the graph.
func ToDeploymentGraph(cfg *config.MachConfig, outPath string) (*Graph, error) {
func ToDeploymentGraph(cfg *config.MachConfig, outPath string, opts ...Option) (*Graph, error) {
o := options{
siteTarget: "",
}

for _, opt := range opts {
opt(&o)
}

g, err := ToDependencyGraph(cfg, outPath)
if err != nil {
return nil, err
}

if err = validateDeployment(g); err != nil {
if err := validateDeployment(g); err != nil {
return nil, err
}

// Remove all nodes that are not independent to site node
if err = reduceNodes(g); err != nil {
if err := reduceNodes(g); err != nil {
return nil, err
}

//Prune to only include the site node if provided
if err := targetSiteNode(g, o.siteTarget); err != nil {
return nil, err
}

Expand Down Expand Up @@ -132,3 +157,34 @@ func reduceNodes(g *Graph) error {

return pErr
}

func targetSiteNode(g *Graph, site string) error {
if site == "" {
return nil
}

if !g.VertexExists(site) {
return fmt.Errorf("site node %s does not exist", site)
}

for _, v := range g.VerticesByType(SiteType) {
if v.Identifier() != site {
var pErr error
_ = graph.DFS(g.Graph, v.Path(), func(p string) bool {
n, err := g.Graph.Vertex(p)
if err != nil {
pErr = err
return true
}

n.SetTargeted(false)

return false
})

return pErr
}
}

return nil
}
Loading
Loading