get.porter.sh/porter@v1.3.0/cmd/porter/installations.go (about) 1 package main 2 3 import ( 4 "get.porter.sh/porter/pkg/porter" 5 "github.com/spf13/cobra" 6 "github.com/spf13/pflag" 7 ) 8 9 func buildInstallationCommands(p *porter.Porter) *cobra.Command { 10 cmd := &cobra.Command{ 11 Use: "installations", 12 Aliases: []string{"inst", "installation"}, 13 Short: "Installation commands", 14 Long: "Commands for working with installations of a bundle", 15 } 16 cmd.Annotations = map[string]string{ 17 "group": "resource", 18 } 19 20 cmd.AddCommand(buildInstallationsListCommand(p)) 21 cmd.AddCommand(buildInstallationShowCommand(p)) 22 cmd.AddCommand(buildInstallationApplyCommand(p)) 23 cmd.AddCommand(buildInstallationOutputsCommands(p)) 24 cmd.AddCommand(buildInstallationDeleteCommand(p)) 25 cmd.AddCommand(buildInstallationLogCommands(p)) 26 cmd.AddCommand(buildInstallationRunsCommands(p)) 27 cmd.AddCommand(buildInstallationInstallCommand(p)) 28 cmd.AddCommand(buildInstallationUpgradeCommand(p)) 29 cmd.AddCommand(buildInstallationInvokeCommand(p)) 30 cmd.AddCommand(buildInstallationUninstallCommand(p)) 31 32 return cmd 33 } 34 35 func buildInstallationsListCommand(p *porter.Porter) *cobra.Command { 36 opts := porter.ListOptions{} 37 38 cmd := &cobra.Command{ 39 Use: "list", 40 Short: "List installed bundles", 41 Long: `List all bundles installed by Porter. 42 43 A listing of bundles currently installed by Porter will be provided, along with metadata such as creation time, last action, last status, etc. 44 Optionally filters the results name, which returns all results whose name contain the provided query. 45 The results may also be filtered by associated labels and the namespace in which the installation is defined. 46 47 Optional output formats include json and yaml.`, 48 Example: ` porter installations list 49 porter installations list -o json 50 porter installations list --all-namespaces, 51 porter installations list --label owner=myname --namespace dev 52 porter installations list --name myapp 53 porter installations list --skip 2 --limit 2`, 54 PreRunE: func(cmd *cobra.Command, args []string) error { 55 return opts.Validate() 56 }, 57 RunE: func(cmd *cobra.Command, args []string) error { 58 return p.PrintInstallations(cmd.Context(), opts) 59 }, 60 } 61 62 f := cmd.Flags() 63 f.StringVarP(&opts.Namespace, "namespace", "n", "", 64 "Filter the installations by namespace. Defaults to the global namespace.") 65 f.BoolVar(&opts.AllNamespaces, "all-namespaces", false, 66 "Include all namespaces in the results.") 67 f.StringVar(&opts.Name, "name", "", 68 "Filter the installations where the name contains the specified substring.") 69 f.StringSliceVarP(&opts.Labels, "label", "l", nil, 70 "Filter the installations by a label formatted as: KEY=VALUE. May be specified multiple times.") 71 f.StringVarP(&opts.RawFormat, "output", "o", "plaintext", 72 "Specify an output format. Allowed values: plaintext, json, yaml") 73 f.Int64Var(&opts.Skip, "skip", 0, 74 "Skip the number of installations by a certain amount. Defaults to 0.") 75 f.Int64Var(&opts.Limit, "limit", 0, 76 "Limit the number of installations by a certain amount. Defaults to 0.") 77 f.StringVar(&opts.FieldSelector, "field-selector", "", "Selector (field query) to filter on, supports '=' (e.g. --field-selector bundle.version=0.2.0,status.action=install). All fields from the json output are supported.") 78 79 return cmd 80 } 81 82 func buildInstallationShowCommand(p *porter.Porter) *cobra.Command { 83 opts := porter.ShowOptions{} 84 85 cmd := cobra.Command{ 86 Use: "show [INSTALLATION]", 87 Short: "Show an installation of a bundle", 88 Long: "Displays info relating to an installation of a bundle, including status and a listing of outputs.", 89 Example: ` porter installation show 90 porter installation show another-bundle 91 92 Optional output formats include json and yaml. 93 `, 94 PreRunE: func(cmd *cobra.Command, args []string) error { 95 return opts.Validate(args, p.Context) 96 }, 97 RunE: func(cmd *cobra.Command, args []string) error { 98 return p.ShowInstallation(cmd.Context(), opts) 99 }, 100 } 101 102 f := cmd.Flags() 103 f.StringVarP(&opts.Namespace, "namespace", "n", "", 104 "Namespace in which the installation is defined. Defaults to the global namespace.") 105 f.StringVarP(&opts.RawFormat, "output", "o", "plaintext", 106 "Specify an output format. Allowed values: plaintext, json, yaml") 107 108 return &cmd 109 } 110 111 func buildInstallationApplyCommand(p *porter.Porter) *cobra.Command { 112 opts := porter.ApplyOptions{} 113 114 cmd := cobra.Command{ 115 Use: "apply FILE", 116 Short: "Apply changes to an installation", 117 Long: `Apply changes from the specified file to an installation. If the installation doesn't already exist, it is created. 118 The installation's bundle is automatically executed if changes are detected. 119 120 When the namespace is not set in the file, the current namespace is used. 121 122 You can use the show command to create the initial file: 123 porter installation show mybuns --output yaml > mybuns.yaml 124 `, 125 Example: ` porter installation apply myapp.yaml 126 porter installation apply myapp.yaml --dry-run 127 porter installation apply myapp.yaml --force`, 128 PreRunE: func(cmd *cobra.Command, args []string) error { 129 return opts.Validate(p.Context, args) 130 }, 131 RunE: func(cmd *cobra.Command, args []string) error { 132 return p.InstallationApply(cmd.Context(), opts) 133 }, 134 } 135 136 f := cmd.Flags() 137 f.StringVarP(&opts.Namespace, "namespace", "n", "", 138 "Namespace in which the installation is defined. Defaults to the namespace defined in the file.") 139 f.BoolVar(&opts.Force, "force", false, 140 "Force the bundle to be executed when no changes are detected.") 141 f.BoolVar(&opts.DryRun, "dry-run", false, 142 "Evaluate if the bundle would be executed based on the changes in the file.") 143 return &cmd 144 } 145 146 func buildInstallationDeleteCommand(p *porter.Porter) *cobra.Command { 147 opts := porter.DeleteOptions{} 148 149 cmd := cobra.Command{ 150 Use: "delete [INSTALLATION]", 151 Short: "Delete an installation", 152 Long: "Deletes all records and outputs associated with an installation", 153 Example: ` porter installation delete 154 porter installation delete wordpress 155 porter installation delete --force 156 `, 157 PreRunE: func(cmd *cobra.Command, args []string) error { 158 return opts.Validate(args, p.Context) 159 }, 160 RunE: func(cmd *cobra.Command, args []string) error { 161 return p.DeleteInstallation(cmd.Context(), opts) 162 }, 163 } 164 165 f := cmd.Flags() 166 f.StringVarP(&opts.Namespace, "namespace", "n", "", 167 "Namespace in which the installation is defined. Defaults to the global namespace.") 168 f.BoolVar(&opts.Force, "force", false, 169 "Force a delete the installation, regardless of last completed action") 170 171 return &cmd 172 } 173 174 func buildInstallationRunsCommands(p *porter.Porter) *cobra.Command { 175 cmd := &cobra.Command{ 176 Use: "runs", 177 Aliases: []string{"run"}, 178 Short: "Commands for working with runs of an Installation", 179 Long: "Commands for working with runs of an Installation", 180 } 181 182 cmd.AddCommand(buildInstallationRunsListCommand(p)) 183 184 return cmd 185 } 186 187 func buildInstallationRunsListCommand(p *porter.Porter) *cobra.Command { 188 opts := porter.RunListOptions{} 189 190 cmd := cobra.Command{ 191 Use: "list", 192 Short: "List runs of an Installation", 193 Long: "List runs of an Installation", 194 Example: ` porter installations runs list [NAME] [--namespace NAMESPACE] [--output FORMAT] 195 196 porter installations runs list myapp --namespace dev 197 198 `, 199 PreRunE: func(cmd *cobra.Command, args []string) error { 200 return opts.Validate(args, p.Context) 201 }, 202 RunE: func(cmd *cobra.Command, args []string) error { 203 return p.PrintInstallationRuns(cmd.Context(), opts) 204 }, 205 } 206 207 f := cmd.Flags() 208 f.StringVarP(&opts.Namespace, "namespace", "n", "", 209 "Namespace in which the installation is defined. Defaults to the global namespace.") 210 f.StringVarP(&opts.RawFormat, "output", "o", "plaintext", 211 "Specify an output format. Allowed values: plaintext, json, yaml") 212 213 return &cmd 214 } 215 216 func buildInstallationInstallCommand(p *porter.Porter) *cobra.Command { 217 opts := porter.NewInstallOptions() 218 cmd := &cobra.Command{ 219 Use: "install [INSTALLATION]", 220 Short: "Create a new installation of a bundle", 221 Long: `Create a new installation of a bundle. 222 223 The first argument is the name of the installation to create. This defaults to the name of the bundle. 224 225 Once a bundle has been successfully installed, the install action cannot be repeated. This is a precaution to avoid accidentally overwriting an existing installation. If you need to re-run install, which is common when authoring a bundle, you can use the --force flag to by-pass this check. 226 227 Porter uses the docker driver as the default runtime for executing a bundle image, but an alternate driver may be supplied via '--driver/-d' or the PORTER_RUNTIME_DRIVER environment variable. 228 For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits. 229 230 The docker driver runs the bundle container using the local Docker host. To use a remote Docker host, set the following environment variables: 231 DOCKER_HOST (required) 232 DOCKER_TLS_VERIFY (optional) 233 DOCKER_CERT_PATH (optional) 234 `, 235 Example: ` porter installation install 236 porter installation install MyAppFromReference --reference ghcr.io/getporter/examples/kubernetes:v0.2.0 --namespace dev 237 porter installation install --reference localhost:5000/ghcr.io/getporter/examples/kubernetes:v0.2.0 --insecure-registry --force 238 porter installation install MyAppInDev --file myapp/bundle.json 239 porter installation install --parameter-set azure --param test-mode=true --param header-color=blue 240 porter installation install --credential-set azure --credential-set kubernetes 241 porter installation install --driver debug 242 porter installation install --label env=dev --label owner=myuser 243 `, 244 PreRunE: func(cmd *cobra.Command, args []string) error { 245 return opts.Validate(cmd.Context(), args, p) 246 }, 247 RunE: func(cmd *cobra.Command, args []string) error { 248 return p.InstallBundle(cmd.Context(), opts) 249 }, 250 } 251 252 f := cmd.Flags() 253 addBundleDefinitionFlags(f, &opts.BundleDefinitionOptions) 254 f.StringVarP(&opts.Namespace, "namespace", "n", "", 255 "Create the installation in the specified namespace. Defaults to the global namespace.") 256 f.StringSliceVarP(&opts.Labels, "label", "l", nil, 257 "Associate the specified labels with the installation. May be specified multiple times.") 258 f.BoolVar(&opts.VerifyBundleBeforeExecution, "verify-bundle", false, "Verify the bundle signature before executing") 259 addBundleActionFlags(f, opts) 260 261 // Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands 262 cmd.Flag("driver").Annotations = map[string][]string{ 263 "viper-key": {"runtime-driver"}, 264 } 265 return cmd 266 } 267 268 func buildInstallationUpgradeCommand(p *porter.Porter) *cobra.Command { 269 opts := porter.NewUpgradeOptions() 270 cmd := &cobra.Command{ 271 Use: "upgrade [INSTALLATION]", 272 Short: "Upgrade an installation", 273 Long: `Upgrade an installation. 274 275 The first argument is the installation name to upgrade. This defaults to the name of the bundle. 276 277 Porter uses the docker driver as the default runtime for executing a bundle image, but an alternate driver may be supplied via '--driver/-d' or the PORTER_RUNTIME_DRIVER environment variable. 278 For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits. 279 280 The docker driver runs the bundle container using the local Docker host. To use a remote Docker host, set the following environment variables: 281 DOCKER_HOST (required) 282 DOCKER_TLS_VERIFY (optional) 283 DOCKER_CERT_PATH (optional) 284 `, 285 Example: ` porter installation upgrade --version 0.2.0 286 porter installation upgrade --reference ghcr.io/getporter/examples/kubernetes:v0.2.0 287 porter installation upgrade --reference localhost:5000/ghcr.io/getporter/examples/kubernetes:v0.2.0 --insecure-registry --force 288 porter installation upgrade MyAppInDev --file myapp/bundle.json 289 porter installation upgrade --parameter-set azure --param test-mode=true --param header-color=blue 290 porter installation upgrade --credential-set azure --credential-set kubernetes 291 porter installation upgrade --driver debug 292 `, 293 PreRunE: func(cmd *cobra.Command, args []string) error { 294 return opts.Validate(cmd.Context(), args, p) 295 }, 296 RunE: func(cmd *cobra.Command, args []string) error { 297 return p.UpgradeBundle(cmd.Context(), opts) 298 }, 299 } 300 301 f := cmd.Flags() 302 addBundleDefinitionFlags(f, &opts.BundleDefinitionOptions) 303 f.StringVarP(&opts.Namespace, "namespace", "n", "", 304 "Namespace of the specified installation. Defaults to the global namespace.") 305 f.StringVar(&opts.Version, "version", "", 306 "Version to which the installation should be upgraded. This represents the version of the bundle, which assumes the convention of setting the bundle tag to its version.") 307 f.BoolVar(&opts.ForceUpgrade, "force-upgrade", false, 308 "Force the upgrade to run even if the current installation is marked as failed.") 309 addBundleActionFlags(f, opts) 310 311 // Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands 312 cmd.Flag("driver").Annotations = map[string][]string{ 313 "viper-key": {"runtime-driver"}, 314 } 315 return cmd 316 } 317 318 func buildInstallationInvokeCommand(p *porter.Porter) *cobra.Command { 319 opts := porter.NewInvokeOptions() 320 cmd := &cobra.Command{ 321 Use: "invoke [INSTALLATION] --action ACTION", 322 Short: "Invoke a custom action on an installation", 323 Long: `Invoke a custom action on an installation. 324 325 The first argument is the installation name upon which to invoke the action. This defaults to the name of the bundle. 326 327 Porter uses the docker driver as the default runtime for executing a bundle image, but an alternate driver may be supplied via '--driver/-d' or the PORTER_RUNTIME_DRIVER environment variable. 328 For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits. 329 330 The docker driver runs the bundle container using the local Docker host. To use a remote Docker host, set the following environment variables: 331 DOCKER_HOST (required) 332 DOCKER_TLS_VERIFY (optional) 333 DOCKER_CERT_PATH (optional) 334 `, 335 Example: ` porter installation invoke --action ACTION 336 porter installation invoke --reference ghcr.io/getporter/examples/kubernetes:v0.2.0 337 porter installation invoke --reference localhost:5000/ghcr.io/getporter/examples/kubernetes:v0.2.0 --insecure-registry --force 338 porter installation invoke --action ACTION MyAppInDev --file myapp/bundle.json 339 porter installation invoke --action ACTION --parameter-set azure --param test-mode=true --param header-color=blue 340 porter installation invoke --action ACTION --credential-set azure --credential-set kubernetes 341 porter installation invoke --action ACTION --driver debug 342 `, 343 PreRunE: func(cmd *cobra.Command, args []string) error { 344 return opts.Validate(cmd.Context(), args, p) 345 }, 346 RunE: func(cmd *cobra.Command, args []string) error { 347 return p.InvokeBundle(cmd.Context(), opts) 348 }, 349 } 350 351 f := cmd.Flags() 352 f.StringVar(&opts.Action, "action", "", 353 "Custom action name to invoke.") 354 f.StringVarP(&opts.Namespace, "namespace", "n", "", 355 "Namespace of the specified installation. Defaults to the global namespace.") 356 addBundleDefinitionFlags(f, &opts.BundleDefinitionOptions) 357 addBundleActionFlags(f, opts) 358 359 // Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands 360 cmd.Flag("driver").Annotations = map[string][]string{ 361 "viper-key": {"runtime-driver"}, 362 } 363 return cmd 364 } 365 366 func buildInstallationUninstallCommand(p *porter.Porter) *cobra.Command { 367 opts := porter.NewUninstallOptions() 368 cmd := &cobra.Command{ 369 Use: "uninstall [INSTALLATION]", 370 Short: "Uninstall an installation", 371 Long: `Uninstall an installation 372 373 The first argument is the installation name to uninstall. This defaults to the name of the bundle. 374 375 Porter uses the docker driver as the default runtime for executing a bundle image, but an alternate driver may be supplied via '--driver/-d'' or the PORTER_RUNTIME_DRIVER environment variable. 376 For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits. 377 378 The docker driver runs the bundle container using the local Docker host. To use a remote Docker host, set the following environment variables: 379 DOCKER_HOST (required) 380 DOCKER_TLS_VERIFY (optional) 381 DOCKER_CERT_PATH (optional) 382 `, 383 Example: ` porter installation uninstall 384 porter installation uninstall --reference ghcr.io/getporter/examples/kubernetes:v0.2.0 385 porter installation uninstall --reference localhost:5000/ghcr.io/getporter/examples/kubernetes:v0.2.0 --insecure-registry --force 386 porter installation uninstall MyAppInDev --file myapp/bundle.json 387 porter installation uninstall --parameter-set azure --param test-mode=true --param header-color=blue 388 porter installation uninstall --credential-set azure --credential-set kubernetes 389 porter installation uninstall --driver debug 390 porter installation uninstall --delete 391 porter installation uninstall --force-delete 392 `, 393 PreRunE: func(cmd *cobra.Command, args []string) error { 394 return opts.Validate(cmd.Context(), args, p) 395 }, 396 RunE: func(cmd *cobra.Command, args []string) error { 397 return p.UninstallBundle(cmd.Context(), opts) 398 }, 399 } 400 401 f := cmd.Flags() 402 f.BoolVar(&opts.Delete, "delete", false, 403 "Delete all records associated with the installation, assuming the uninstall action succeeds") 404 f.BoolVar(&opts.ForceDelete, "force-delete", false, 405 "UNSAFE. Delete all records associated with the installation, even if uninstall fails. This is intended for cleaning up test data and is not recommended for production environments.") 406 f.StringVarP(&opts.Namespace, "namespace", "n", "", 407 "Namespace of the specified installation. Defaults to the global namespace.") 408 addBundleDefinitionFlags(f, &opts.BundleDefinitionOptions) 409 addBundleActionFlags(f, opts) 410 411 // Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands 412 cmd.Flag("driver").Annotations = map[string][]string{ 413 "viper-key": {"runtime-driver"}, 414 } 415 return cmd 416 } 417 418 // Add flags for command that execute a bundle (install, upgrade, invoke and uninstall) 419 func addBundleActionFlags(f *pflag.FlagSet, actionOpts porter.BundleAction) { 420 opts := actionOpts.GetOptions() 421 addBundlePullFlags(f, &opts.BundlePullOptions) 422 f.BoolVar(&opts.AllowDockerHostAccess, "allow-docker-host-access", false, 423 "Controls if the bundle should have access to the host's Docker daemon with elevated privileges. See https://porter.sh/configuration/#allow-docker-host-access for the full implications of this flag.") 424 f.StringArrayVar(&opts.HostVolumeMounts, "mount-host-volume", nil, "Mount a host volume into the bundle. Format is <host path>:<container path>[:<option>]. May be specified multiple times. Option can be ro (read-only), rw (read-write), default is ro.") 425 f.BoolVar(&opts.NoLogs, "no-logs", false, 426 "Do not persist the bundle execution logs") 427 f.StringArrayVarP(&opts.ParameterSets, "parameter-set", "p", nil, 428 "Parameter sets to use when running the bundle. It should be a named set of parameters and may be specified multiple times.") 429 f.StringArrayVar(&opts.Params, "param", nil, 430 "Define an individual parameter in the form NAME=VALUE. Overrides parameters otherwise set via --parameter-set. May be specified multiple times.") 431 f.StringArrayVarP(&opts.CredentialIdentifiers, "credential-set", "c", nil, 432 "Credential sets to use when running the bundle. It should be a named set of credentials and may be specified multiple times.") 433 f.StringVarP(&opts.Driver, "driver", "d", porter.DefaultDriver, 434 "Specify a driver to use. Allowed values: docker, debug") 435 f.BoolVar(&opts.DebugMode, "debug", false, 436 "Run the bundle in debug mode.") 437 438 // Gracefully support any renamed flags 439 f.StringArrayVar(&opts.CredentialIdentifiers, "cred", nil, "DEPRECATED") 440 _ = f.MarkDeprecated("cred", "please use credential-set instead.") 441 }