Documentation ¶
Overview ¶
Package cmd provides the command line functions of the crunchy CLI
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI ¶
Package cmd provides the command line functions of the crunchy CLI
Index ¶
Constants ¶
const TreeBranch = "\t"
const TreeTrunk = "\t"
Variables ¶
var ( // the source cluster used for the clone, e.g. "oldcluster" SourceClusterName string // the target/destination cluster used for the clone, e.g. "newcluster" TargetClusterName string // BackrestStorageSource represents the data source to use (e.g. s3 or local) when both s3 // and local are enabled in the cluster being cloned BackrestStorageSource string )
var ( // the resource requests / limits for PostgreSQL instances CPURequest, MemoryRequest string CPULimit, MemoryLimit string // the resource requests / limits for the pgBackRest repository BackrestCPURequest, BackrestMemoryRequest string BackrestCPULimit, BackrestMemoryLimit string // the resource requests / limits for pgBouncer instances PgBouncerCPURequest, PgBouncerMemoryRequest string PgBouncerCPULimit, PgBouncerMemoryLimit string )
group the various container resource requests together, i.e. for CPU/Memory
var ( // TLSOnly indicates that only TLS connections will be accepted for a // PostgreSQL cluster TLSOnly bool // TLSSecret is the name of the secret that contains the TLS information for // enabling TLS in a PostgreSQL cluster TLSSecret string // ReplicationTLSSecret is the name of the secret that contains the TLS // information for enabling certificate-based authentication between instances // in a PostgreSQL cluster, particularly for replication ReplicationTLSSecret string // CASecret is the name of the secret that contains the CA information for // enabling TLS in a PostgreSQL cluster CASecret string )
variables used for setting up TLS-enabled PostgreSQL clusters
var ( // DisableLogin allows a user to disable the ability for a PostgreSQL uesr to // log in DisableLogin bool // EnableLogin allows a user to enable the ability for a PostgreSQL uesr to // log in EnableLogin bool // ExpireUser sets a user to having their password expired ExpireUser bool // PgoroleChangePermissions does something with the pgouser access controls, // I'm not sure but I wanted this at least to be documented PgoroleChangePermissions bool // RotatePassword is a flag that allows one to specify that a password be // automatically rotated, such as a service account type password RotatePassword bool // DisableStandby can be used to disable standby mode when enabled in an existing cluster DisableStandby bool // EnableStandby can be used to enable standby mode in an existing cluster EnableStandby bool // Shutdown is used to indicate that the cluster should be shutdown Shutdown bool // Startup is used to indicate that the cluster should be started (assuming it is shutdown) Startup bool )
var APIServerURL string
var AllFlag bool
var AllNamespaces bool
var ArchiveFlag, DisableAutofailFlag, EnableAutofailFlag, PgbouncerFlag, MetricsFlag, BadgerFlag bool
var BackrestPVCSize string
var BackrestRepoPath string
BackrestRepoPath allows the pgBackRest repo path to be defined instead of using the default
var BackrestRestoreFrom string
var BackrestS3Bucket string
var BackrestS3CASecretName string
BackrestS3CASecretName, if provided, is the name of a secret to use that contains a CA certificate to use for the pgBackRest repo
var BackrestS3Endpoint string
var BackrestS3Key string
var BackrestS3KeySecret string
var BackrestS3Region string
var BackrestS3URIStyle string
var BackrestS3VerifyTLS bool
var BackrestStorageConfig, ReplicaStorageConfig, StorageConfig string
var BackrestStorageType string
var BackupOpts string
var BackupPath, BackupPVC string
var BackupType string
var CCPImage string
var CCPImagePrefix string
var CCPImageTag string
var ClientVersionOnly bool
ClientVersionOnly indicates that only the client version should be returned, not make a call to the server
var ClusterReplicaCount int
var ConfigMapName string
unused but coming soon to a theatre near you
var CreateCmd = &cobra.Command{ Use: "create", Short: "Create a Postgres Operator resource", Long: `CREATE allows you to create a new Operator resource. For example: pgo create cluster pgo create pgadmin pgo create pgbouncer pgo create pgouser pgo create pgorole pgo create policy pgo create namespace pgo create user`, Run: func(cmd *cobra.Command, args []string) { log.Debug("create called") if len(args) == 0 { fmt.Println(`Error: You must specify the type of resource to create. Valid resource types include: * cluster * pgadmin * pgbouncer * pgouser * pgorole * policy * namespace * user`) } else { switch args[0] { case "cluster", "pgbouncer", "pgouser", "pgorole", "policy", "user", "namespace": break default: fmt.Println(`Error: You must specify the type of resource to create. Valid resource types include: * cluster * pgadmin * pgbouncer * pgouser * pgorole * policy * namespace * user`) } } }, }
var CustomConfig string
var Database string
var DebugFlag bool
var DeleteData bool
flags used by more than 1 command
var DeleteLabel bool
var DryRun bool
var EXCLUDE_OS_TRUST bool
var Expired int
Expired expired flag
var GREEN func(a ...interface{}) string
var IgnoreValidation bool
IgnoreValidation stores the flag input value that determines whether image tag version checking should be done before allowing an upgrade to continue
var KeepBackups bool
KeepBackups, If set to "true", indicates that backups should be stored even after a cluster is deleted
var KeepData bool
KeepData, If set to "true", indicates that cluster data should be stored even after a cluster is deleted. This is DEPRECATED
var LabelCmdLabel string
var LabelMap map[string]string
var Labelselector string
var LoadConfig string
var ManagedUser bool
var Namespace string
var NoPrompt bool
NoPrompt, If set to "true", indicates that the user should not be prompted before executing a delete command
var NodeLabel string
var OutputFormat string
var PGBackRestType string
var PGDumpDB string
PGDumpDB is used to store the name of the pgDump database when performing either a backup or restore
var PGOEventAddress string
var PGOImagePrefix string
var PGONamespace string
var PGO_CA_CERT, PGO_CLIENT_CERT, PGO_CLIENT_KEY string
var PGO_DISABLE_TLS bool
var PITRTarget string
var PVCName string
var PVCSize string
var Password string
var PasswordAgeDays int
PasswordAgeDays password age flag
var PasswordLength int
PasswordLength password length flag
var PasswordReplication string
PasswordReplication specifies the password for the cluster replication user
var PasswordSuperuser string
PasswordSuperuser specifies the password for the cluster superuser
var PasswordType string
PasswordType allows one to specify if the password should be MD5 or SCRAM we presently ensure it defaults to MD5
var PasswordValidAlways bool
PasswordValidAlways allows a user to explicitly set that their passowrd is always valid (i.e. no expiration time)
var Permissions string
var PgBouncerReplicas int32
PgBouncerReplicas is the total number of replica pods to deploy with a pgBouncer Deployment
var PgBouncerUninstall bool
PgBouncerUninstall is used to ensure the objects intalled in PostgreSQL on behalf of pgbouncer are either not applied (in the case of a cluster create) or are removed (in the case of a pgo delete pgbouncer)
var PgouserChangePassword bool
var PgouserPassword, PgouserRoles, PgouserNamespaces string
var PodAntiAffinity string
var PodAntiAffinityPgBackRest string
var PodAntiAffinityPgBouncer string
var PoliciesFlag, PolicyFile, PolicyURL string
var Query bool
var RED func(a ...interface{}) string
var ReplicaCount int
var RestoreFrom string
var RestoreType string
var RootCmd = &cobra.Command{
Use: "pgo",
Short: "The pgo command line interface.",
Long: `The pgo command line interface lets you create and manage PostgreSQL clusters.`,
}
RootCmd represents the base command when called without any subcommands
var Schedule string
var ScheduleDatabase string
var ScheduleName string
var ScheduleOptions string
var SchedulePolicy string
var ScheduleSecret string
var ScheduleType string
var Secret string
var SecretFrom string
var Selector string
var ServiceType string
var SessionCredentials msgs.BasicAuthCredentials
SessionCredentials stores the PGO user, PGO password and the PGO APIServer URL
var ShowBackupCmd = &cobra.Command{ Use: "backup", Short: "Show backup information", Long: `Show backup information. For example: pgo show backup mycluser`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } if len(args) == 0 { fmt.Println("Error: cluster name(s) required for this command.") } else { if showBackupType == "" || showBackupType == config.LABEL_BACKUP_TYPE_BACKREST { showBackrest(args, Namespace) } else if showBackupType == config.LABEL_BACKUP_TYPE_PGDUMP { showpgDump(args, Namespace) } else { fmt.Println("Error: Valid backup-type values are pgbackrest and pgdump. The default if not supplied is pgbackrest.") } } }, }
showBackupCmd represents the show backup command
var ShowClusterCmd = &cobra.Command{ Use: "cluster", Short: "Show cluster information", Long: `Show a PostgreSQL cluster. For example: pgo show cluster --all pgo show cluster mycluster`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } if Selector == "" && len(args) == 0 && !AllFlag { fmt.Println("Error: Cluster name(s), --selector, or --all required for this command.") } else { showCluster(args, Namespace) } }, }
ShowClusterCmd represents the show cluster command
var ShowCmd = &cobra.Command{ Use: "show", Short: "Show the description of a cluster", Long: `Show allows you to show the details of a policy, backup, pvc, or cluster. For example: pgo show backup mycluster pgo show backup mycluster --backup-type=pgbackrest pgo show cluster mycluster pgo show config pgo show pgouser someuser pgo show policy policy1 pgo show pvc mycluster pgo show namespace pgo show workflow 25927091-b343-4017-be4b-71575f0b3eb5 pgo show user --selector=name=mycluster`, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { fmt.Println(`Error: You must specify the type of resource to show. Valid resource types include: * backup * cluster * config * pgadmin * pgbouncer * pgouser * policy * pvc * namespace * workflow * user `) } else { switch args[0] { case "backup", "cluster", "config", "pgadmin", "pgbouncer", "pgouser", "policy", "pvc", "schedule", "namespace", "workflow", "user": break default: fmt.Println(`Error: You must specify the type of resource to show. Valid resource types include: * backup * cluster * config * pgadmin * pgbouncer * pgouser * policy * pvc * namespace * workflow * user`) } } }, }
var ShowConfigCmd = &cobra.Command{ Use: "config", Short: "Show configuration information", Long: `Show configuration information for the Operator. For example: pgo show config`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } showConfig(args, Namespace) }, }
var ShowNamespaceCmd = &cobra.Command{ Use: "namespace", Short: "Show namespace information", Long: `Show namespace information for the Operator. For example: pgo show namespace`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } showNamespace(args) }, }
var ShowPVCCmd = &cobra.Command{ Use: "pvc", Short: "Show PVC information for a cluster", Long: `Show PVC information. For example: pgo show pvc mycluster pgo show pvc --all`, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 && !AllFlag { fmt.Println("Error: Cluster name(s) or --all required for this command.") } else { if Namespace == "" { Namespace = PGONamespace } showPVC(args, Namespace) } }, }
var ShowPgAdminCmd = &cobra.Command{ Use: "pgadmin", Short: "Show pgadmin deployment information", Long: `Show service information about a pgadmin deployment. For example: pgo show pgadmin thecluster pgo show pgadmin --selector=app=theapp `, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } showPgAdmin(Namespace, args) }, }
var ShowPgBouncerCmd = &cobra.Command{ Use: "pgbouncer", Short: "Show pgbouncer deployment information", Long: `Show user, password, and service information about a pgbouncer deployment. For example: pgo show pgbouncer hacluster pgo show pgbouncer --selector=app=payment `, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } showPgBouncer(Namespace, args) }, }
var ShowPgoroleCmd = &cobra.Command{ Use: "pgorole", Short: "Show pgorole information", Long: `Show pgorole information . For example: pgo show pgorole somerole`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } showPgorole(args, Namespace) }, }
var ShowPgouserCmd = &cobra.Command{ Use: "pgouser", Short: "Show pgouser information", Long: `Show pgouser information for an Operator user. For example: pgo show pgouser someuser`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } showPgouser(args, Namespace) }, }
var ShowPolicyCmd = &cobra.Command{ Use: "policy", Short: "Show policy information", Long: `Show policy information. For example: pgo show policy --all pgo show policy policy1`, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 && !AllFlag { fmt.Println("Error: Policy name(s) or --all required for this command.") } else { if Namespace == "" { Namespace = PGONamespace } showPolicy(args, Namespace) } }, }
var ShowScheduleCmd = &cobra.Command{ Use: "schedule", Short: "Show schedule information", Long: `Show cron-like schedules. For example: pgo show schedule mycluster pgo show schedule --selector=pg-cluster=mycluster pgo show schedule --schedule-name=mycluster-pgbackrest-full`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } if len(args) == 0 && Selector == "" && ScheduleName == "" { fmt.Println("Error: cluster name, schedule name or selector is required to show a schedule.") return } showSchedule(args, Namespace) }, }
ShowScheduleCmd represents the show schedule command
var ShowSystemAccounts bool
ShowSystemAccounts enables the display of the PostgreSQL user accounts that perform system functions, such as the "postgres" user
var ShowUserCmd = &cobra.Command{ Use: "user", Short: "Show user information", Long: `Show users on a cluster. For example: pgo show user --all pgo show user mycluster pgo show user --selector=name=nycluster`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } if Selector == "" && AllFlag == false && len(args) == 0 { fmt.Println("Error: --selector, --all, or cluster name()s required for this command") } else { showUser(args, Namespace) } }, }
ShowUserCmd represents the show user command
var ShowWorkflowCmd = &cobra.Command{ Use: "workflow", Short: "Show workflow information", Long: `Show workflow information for a given workflow. For example: pgo show workflow 25927091-b343-4017-be4b-71575f0b3eb5`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } showWorkflow(args, Namespace) }, }
var Standby bool
Standby determines whether or not the cluster should be created as a standby cluster
var Summary bool
var SyncReplication bool
var Tablespaces []string
var Target string
var Targets []string
var UpdateClusterCmd = &cobra.Command{ Use: "cluster", Short: "Update a PostgreSQL cluster", Long: `Update a PostgreSQL cluster. For example: pgo update cluster mycluster --autofail=false pgo update cluster mycluster myothercluster --disable-autofail pgo update cluster --selector=name=mycluster --disable-autofail pgo update cluster --all --enable-autofail`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } if len(args) == 0 && Selector == "" && !AllFlag { fmt.Println("Error: A cluster name(s) or selector or --all is required for this command.") os.Exit(1) } if EnableAutofailFlag && DisableAutofailFlag { fmt.Println("Error: Cannot set --enable-autofail and --disable-autofail simultaneously") os.Exit(1) } if EnableStandby { fmt.Println("Enabling standby mode will result in the deltion of all PVCs " + "for this cluster!\nData will only be retained if the proper retention policy " + "is configured for any associated storage classes and/or persistent volumes.\n" + "Please proceed with caution.") } if DisableStandby { fmt.Println("Disabling standby mode will enable database writes for this " + "cluster.\nPlease ensure the cluster this standby cluster is replicating " + "from has been properly shutdown before proceeding!") } if len(Tablespaces) > 0 { fmt.Println("Adding tablespaces can cause downtime.") } if CPURequest != "" || CPULimit != "" { fmt.Println("Updating CPU resources can cause downtime.") } if MemoryRequest != "" || MemoryLimit != "" { fmt.Println("Updating memory resources can cause downtime.") } if BackrestCPURequest != "" || BackrestMemoryRequest != "" || BackrestCPULimit != "" || BackrestMemoryLimit != "" { fmt.Println("Updating pgBackRest resources can cause temporary unavailability of backups and WAL archives.") } if !util.AskForConfirmation(NoPrompt, "") { fmt.Println("Aborting...") return } updateCluster(args, Namespace) }, }
UpdateClusterCmd ...
var UpdateCmd = &cobra.Command{ Use: "update", Short: "Update a pgouser, pgorole, or cluster", Long: `The update command allows you to update a pgouser, pgorole, or cluster. For example: pgo update cluster --selector=name=mycluster --autofail=false pgo update cluster --all --autofail=true pgo update namespace mynamespace pgo update pgbouncer mycluster --rotate-password pgo update pgorole somerole --pgorole-permission="Cat" pgo update pgouser someuser --pgouser-password=somenewpassword pgo update pgouser someuser --pgouser-roles="role1,role2" pgo update pgouser someuser --pgouser-namespaces="pgouser2" pgo update pgorole somerole --pgorole-permission="Cat" pgo update user mycluster --username=testuser --selector=name=mycluster --password=somepassword`, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { fmt.Println(`Error: You must specify the type of resource to update. Valid resource types include: * cluster * namespace * pgbouncer * pgorole * pgouser * user`) } else { switch args[0] { case "user", "cluster", "pgbouncer", "pgouser", "pgorole", "namespace": break default: fmt.Println(`Error: You must specify the type of resource to update. Valid resource types include: * cluster * namespace * pgbouncer * pgorole * pgouser * user`) } } }, }
UpdateCmd represents the update command
var UpdateNamespaceCmd = &cobra.Command{ Use: "namespace", Short: "Update a namespace, applying Operator RBAC", Long: `UPDATE allows you to update a Namespace. For example: pgo update namespace mynamespace`, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { fmt.Println("Error: You must specify the name of a Namespace.") } else { updateNamespace(args) } }, }
var UpdatePgBouncerCmd = &cobra.Command{ Use: "pgbouncer", Short: "Update a pgBouncer deployment for a PostgreSQL cluster", Long: `Used to update the pgBouncer deployment for a PostgreSQL cluster, such as by rotating a password. For example: pgo update pgbouncer hacluster --rotate-password `, Run: func(cmd *cobra.Command, args []string) { if !util.AskForConfirmation(NoPrompt, pgBouncerPrompt) { fmt.Println("Aborting...") return } if Namespace == "" { Namespace = PGONamespace } if PgBouncerReplicas < 0 { fmt.Println("Error: You must specify one or more replicas.") os.Exit(1) } updatePgBouncer(Namespace, args) }, }
var UpdatePgoroleCmd = &cobra.Command{ Use: "pgorole", Short: "Update a pgorole", Long: `UPDATE allows you to update a pgo role. For example: pgo update pgorole somerole --permissions="Cat,Ls`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } if len(args) == 0 { fmt.Println("Error: You must specify the name of a pgorole.") } else { updatePgorole(args, Namespace) } }, }
var UpdatePgouserCmd = &cobra.Command{ Use: "pgouser", Short: "Update a pgouser", Long: `UPDATE allows you to update a pgo user. For example: pgo update pgouser myuser --pgouser-roles=somerole pgo update pgouser myuser --pgouser-password=somepassword --pgouser-roles=somerole pgo update pgouser myuser --pgouser-password=somepassword --no-prompt`, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } if len(args) == 0 { fmt.Println("Error: You must specify the name of a pgouser.") } else { updatePgouser(args, Namespace) } }, }
var UpdateUserCmd = &cobra.Command{ Use: "user", Short: "Update a PostgreSQL user", Long: `Allows the ability to perform various user management functions for PostgreSQL users. For example: //change a password, set valid days for 40 days from now pgo update user mycluster --username=someuser --password=foo //expire password for a user pgo update user mycluster --username=someuser --expire-user //Update all passwords older than the number of days specified pgo update user mycluster --expired=45 --password-length=8 # Disable the ability for a user to log into the PostgreSQL cluster pgo update user mycluster --username=foobar --disable-login # Enable the ability for a user to log into the PostgreSQL cluster pgo update user mycluster --username=foobar --enable-login `, Run: func(cmd *cobra.Command, args []string) { if Namespace == "" { Namespace = PGONamespace } if !AllFlag && Selector == "" && len(args) == 0 { fmt.Println("Error: You must specify a --selector, --all or a list of clusters.") os.Exit(1) } if Username == "" && Expired == 0 { fmt.Println("Error: You must specify either --username or --expired") os.Exit(1) } if EnableLogin && DisableLogin { fmt.Println("Error: Cannot set --enable-login and --disable-login simultaneously") os.Exit(1) } updateUser(args, Namespace) }, }
var UpgradeCCPImageTag string
UpgradeCCPImageTag stores the image tag for the cluster being upgraded. This is specifically required when upgrading PostGIS clusters because that tag will necessarily differ from the other images tags due to the inclusion of the PostGIS version.
var UpgradeCmd = &cobra.Command{ Use: "upgrade", Short: "Perform a cluster upgrade.", Long: `UPGRADE allows you to perform a comprehensive PGCluster upgrade (for use after performing a Postgres Operator upgrade). For example: pgo upgrade mycluster Upgrades the cluster for use with the upgraded Postgres Operator version.`, Run: func(cmd *cobra.Command, args []string) { log.Debug("cluster upgrade called") if Namespace == "" { Namespace = PGONamespace } if len(args) == 0 && Selector == "" { fmt.Println(`Error: You must specify the cluster to upgrade.`) } else { fmt.Println("All active replicas will be scaled down and the primary database in this cluster will be stopped and recreated as part of this workflow!") if util.AskForConfirmation(NoPrompt, "") { createUpgrade(args, Namespace) } else { fmt.Println("Aborting...") } } }, }
var UserLabels string
var Username string
Username is a postgres username
var WALPVCSize string
var WALStorageConfig string
var YELLOW func(a ...interface{}) string
Functions ¶
func Execute ¶
func Execute()
Execute adds all child commands to the root command sets flags appropriately. This is called by main.main(). It only needs to happen once to the rootCmd.
func GetTLSTransport ¶
GetTLSTransport returns an http.Transport configured with environmental TLS client settings
func NewAPIClient ¶
NewAPIClient returns an http client configured with a tls.Config based on environmental settings and a default timeout
func NewAPIClientTLS ¶
NewAPIClientTLS returns an http client configured with a tls.Config based on environmental settings and a default timeout It returns an error if required environmental settings are missing
func SetSessionUserCredentials ¶
func SetSessionUserCredentials()
SetSessionUserCredentials gathers the pgouser and password information and stores them for use by the PGO client
Types ¶
type TailHandler ¶
type TailHandler struct {
// contains filtered or unexported fields
}
func (*TailHandler) HandleMessage ¶
func (th *TailHandler) HandleMessage(m *nsq.Message) error
Source Files ¶
- auth.go
- backrest.go
- backup.go
- cat.go
- clone.go
- cluster.go
- common.go
- config.go
- create.go
- delete.go
- df.go
- failover.go
- flags.go
- label.go
- load.go
- namespace.go
- pgadmin.go
- pgbouncer.go
- pgdump.go
- pgorole.go
- pgouser.go
- policy.go
- pvc.go
- reload.go
- restart.go
- restore.go
- root.go
- scale.go
- scaledown.go
- schedule.go
- show.go
- status.go
- test.go
- update.go
- upgrade.go
- user.go
- version.go
- watch.go
- workflow.go