Documentation
¶
Index ¶
- Variables
- func DescribeCanonicalAddress(r sq.BaseRunner, email utils.EmailAddress) (bool, error)
- func Execute()
- func ParseDomainFQDNArgs(args []string) []string
- func ParseEmailArgs(args []string) []utils.EmailAddress
- func ParseEmailOrWildcardArgs(args []string) []utils.EmailAddressOrWildcard
- func PasswordHash(password, method string, options string) (string, error)
- func ReadFileValue(path string) (string, error)
- func ReadPassword(fromStdin bool) (string, error)
- func ReadPasswordHashed(method string, options string, fromStdin bool) (string, error)
- func RenderMetaSection(createdAt time.Time, updatedAt time.Time, deletedAt *time.Time) string
- func ResolveDynamicSourceArg(directValue, filePath, envVarName string) (string, error)
Constants ¶
This section is empty.
Variables ¶
View Source
var CreateAliasTargetsCmd = &cobra.Command{ Use: "alias-targets [flags] <alias-email> <target-email> [<target-email>...]", Aliases: []string{"alias-target", "targets", "target"}, Short: "Creates new alias targets for an alias", Long: "Creates new alias targets for an alias.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { flagForward, _ := cmd.Flags().GetBool("forward") flagSend, _ := cmd.Flags().GetBool("send") argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } argAliasEmail := argEmails[0] argTargetEmails := argEmails[1:] options := db.AliasesTargetsCreateOptions{ ForwardEnabled: flagForward, SendEnabled: flagSend, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argTargetEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.AliasesTargets(tx).Create(argAliasEmail, item, options) }, ItemString: func(item utils.EmailAddress) string { return argAliasEmail.String() + " -> " + item.String() }, FailureMessage: "failed to create alias target", SuccessMessage: "Successfully created alias target", } runner.Run() return nil }, }
View Source
var CreateAliasesCmd = &cobra.Command{ Use: "aliases [flags] <email> [<email>...]", Aliases: []string{"alias"}, Short: "Creates new aliases", Long: "Creates new aliases.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagDisabled, _ := cmd.Flags().GetBool("disabled") argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.AliasesCreateOptions{ Disabled: flagDisabled, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Aliases(tx).Create(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to create alias", SuccessMessage: "Successfully created alias", } runner.Run() return nil }, }
View Source
var CreateCmd = &cobra.Command{
Use: "create",
Short: "Create mail system objects",
}
View Source
var CreateDomainCatchallTargetsCmd = &cobra.Command{ Use: "catchall-targets [flags] <domain> <target-email> [<target-email>...]", Aliases: []string{"catchall-target", "catchalls", "catchall"}, Short: "Creates new catch-all targets for a domain", Long: "Creates new catch-all targets for a domain.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { flagForward, _ := cmd.Flags().GetBool("forward") flagFallbackOnly, _ := cmd.Flags().GetBool("fallback-only") argDomain := args[0] argEmails := ParseEmailArgs(args[1:]) if len(argEmails) != len(args)-1 { return fmt.Errorf("invalid email arguments") } options := db.DomainsCatchallTargetsCreateOptions{ ForwardEnabled: flagForward, FallbackOnly: flagFallbackOnly, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.DomainsCatchallTargets(tx).Create(argDomain, item, options) }, ItemString: func(item utils.EmailAddress) string { return "@" + argDomain + " -> " + item.String() }, FailureMessage: "failed to create catchall target", SuccessMessage: "Successfully created catchall target", } runner.Run() return nil }, }
View Source
var CreateDomainsCmd = &cobra.Command{ Use: "domains [flags] <fqdn> [<fqdn>...]", Aliases: []string{"domain"}, Short: "Creates new domains", Long: "Creates new domains. Supported domain types are 'managed', 'relayed', 'alias' and 'canonical'.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagDisabled, _ := cmd.Flags().GetBool("disabled") flagType, _ := cmd.Flags().GetString("type") flagTransport, _ := cmd.Flags().GetString("transport") flagTargetDomain, _ := cmd.Flags().GetString("target-domain") domainType := strings.ToLower(flagType) switch domainType { case "managed", "relayed": if flagTransport == "" { return fmt.Errorf("transport name is required for %s domains", domainType) } case "canonical": if flagTargetDomain == "" { return fmt.Errorf("target domain FQDN is required for canonical domains") } case "alias": default: return fmt.Errorf("invalid domain type: %s (must be 'managed', 'relayed', 'alias' or 'canonical')", flagType) } argDomains := ParseDomainFQDNArgs(args) if len(argDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } options := db.DomainsCreateOptions{ DomainType: domainType, TransportName: flagTransport, TargetDomainFQDN: flagTargetDomain, Enabled: !flagDisabled, } runner := db.TxForEachRunner[string]{ Items: argDomains, Exec: func(tx *sql.Tx, item string) error { return db.Domains(tx).Create(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to create domain", SuccessMessage: "Successfully created domain", } runner.Run() return nil }, }
View Source
var CreateMailboxesCmd = &cobra.Command{ Use: "mailboxes <email> [<email>...]", Aliases: []string{"mailbox"}, Short: "Creates new mailboxes", Long: "Creates new mailboxes.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPassword, _ := cmd.Flags().GetBool("password") flagPasswordStdin, _ := cmd.Flags().GetBool("password-stdin") flagPasswordMethod, _ := cmd.Flags().GetString("password-method") flagPasswordHashOptions, _ := cmd.Flags().GetString("password-hash-options") flagQuota, _ := cmd.Flags().GetInt32("quota") flagTransportName, _ := cmd.Flags().GetString("transport") flagLoginDisabled, _ := cmd.Flags().GetBool("login-disabled") flagReceivingDisabled, _ := cmd.Flags().GetBool("receiving-disabled") flagSendingDisabled, _ := cmd.Flags().GetBool("sending-disabled") if flagPassword && flagPasswordStdin { return fmt.Errorf("cannot use both --password and --password-stdin") } if len(args) > 1 && (flagPassword || flagPasswordStdin) { return fmt.Errorf("cannot set password while creating multiple mailboxes") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.MailboxesCreateOptions{ LoginEnabled: !flagLoginDisabled, ReceivingEnabled: !flagReceivingDisabled, SendingEnabled: !flagSendingDisabled, } if flagPassword || flagPasswordStdin { passwordHash, err := ReadPasswordHashed(flagPasswordMethod, flagPasswordHashOptions, flagPasswordStdin) if err != nil { utils.PrintErrorWithMessage("failed to read password", err) return nil } options.PasswordHash.Valid = true options.PasswordHash.String = passwordHash } if flagQuota > 0 { options.Quota.Valid = true options.Quota.Int32 = flagQuota } if flagTransportName != "" { options.TransportName.Valid = true options.TransportName.String = flagTransportName } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Mailboxes(tx).Create(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to create mailbox", SuccessMessage: "Successfully created mailbox", } runner.Run() return nil }, }
View Source
var CreateRecipientsRelayedCmd = &cobra.Command{ Use: "recipients-relayed [flags] <email> [<email>...]", Aliases: []string{"recipient-relayed", "relayed-recipients", "relayed-recipient", "relayed"}, Short: "Creates new relayed recipients", Long: "Creates new relayed recipients.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagDisabled, _ := cmd.Flags().GetBool("disabled") argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.RecipientsRelayedCreateOptions{ Enabled: !flagDisabled, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.RecipientsRelayed(tx).Create(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to create relayed recipient", SuccessMessage: "Successfully created relayed recipient", } runner.Run() return nil }, }
View Source
var CreateRemoteSendGrantsCmd = &cobra.Command{ Use: "send-grants <remote-name> <email> [<email>...]", Aliases: []string{"send-grant"}, Short: "Creates new send grants for a remote", Long: "Creates new send grants for a remote.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argRemoteName := args[0] argEmails := ParseEmailOrWildcardArgs(args[1:]) if len(argEmails) != len(args[1:]) { return fmt.Errorf("invalid email argument") } options := db.RemotesSendGrantsCreateOptions{} runner := db.TxForEachRunner[utils.EmailAddressOrWildcard]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddressOrWildcard) error { return db.RemotesSendGrants(tx).Create(argRemoteName, item, options) }, ItemString: func(item utils.EmailAddressOrWildcard) string { return argRemoteName + " -> " + item.String() }, FailureMessage: "failed to create send grant", SuccessMessage: "Successfully created send grant", } runner.Run() return nil }, }
View Source
var CreateRemotesCmd = &cobra.Command{ Use: "remotes <hostname> [<hostname>...]", Aliases: []string{"remote"}, Short: "Creates new remotes", Long: "Creates new remotes.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPassword, _ := cmd.Flags().GetBool("password") flagPasswordStdin, _ := cmd.Flags().GetBool("password-stdin") flagPasswordMethod, _ := cmd.Flags().GetString("password-method") flagPasswordHashOptions, _ := cmd.Flags().GetString("password-hash-options") flagDisabled, _ := cmd.Flags().GetBool("disabled") if flagPassword && flagPasswordStdin { return fmt.Errorf("cannot use both --password and --password-stdin") } if len(args) > 1 && (flagPassword || flagPasswordStdin) { return fmt.Errorf("cannot set password while creating multiple remotes") } options := db.RemotesCreateOptions{ Enabled: !flagDisabled, } if flagPassword || flagPasswordStdin { passwordHash, err := ReadPasswordHashed(flagPasswordMethod, flagPasswordHashOptions, flagPasswordStdin) if err != nil { utils.PrintErrorWithMessage("failed to read password", err) return nil } options.PasswordHash = sql.NullString{ String: passwordHash, Valid: true, } } runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Remotes(tx).Create(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to create remote", SuccessMessage: "Successfully created remote", } runner.Run() return nil }, }
View Source
var CreateTransportsCmd = &cobra.Command{ Use: "transport <name>", Short: "Creates a new transport", Long: "Creates a new transport.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { name := args[0] flagMethod, _ := cmd.Flags().GetString("method") flagHost, _ := cmd.Flags().GetString("host") flagPort, _ := cmd.Flags().GetUint16("port") flagMxLookup, _ := cmd.Flags().GetBool("mx-lookup") options := db.TransportsCreateOptions{ Method: flagMethod, Host: flagHost, MxLookup: flagMxLookup, } if flagPort > 0 { options.Port = sql.NullInt32{Int32: int32(flagPort), Valid: true} } runner := db.TxRunner{ Exec: func(tx *sql.Tx) error { return db.Transports(tx).Create(name, options) }, ItemString: name, FailureMessage: "failed to create transport", SuccessMessage: "Successfully created transport", } runner.Run() return nil }, }
View Source
var DeleteAliasTargetsCmd = &cobra.Command{ Use: "alias-targets [flags] <alias-email> <target-email> [<target-email>...]", Aliases: []string{"alias-target", "targets", "target"}, Short: "Deletes alias targets from an alias", Long: `Deletes alias targets from an alias. By default performs a soft delete. Use --permanent for hard delete.`, Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") if flagPermanent && flagForce { return fmt.Errorf("cannot use --permanent and --force flags together") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } argAliasEmail := argEmails[0] argTargetEmails := argEmails[1:] options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argTargetEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.AliasesTargets(tx).Delete(argAliasEmail, item, options) }, ItemString: func(item utils.EmailAddress) string { return argAliasEmail.String() + " -> " + item.String() }, FailureMessage: "failed to delete alias target", SuccessMessage: "Successfully deleted alias target", } if flagPermanent { runner.SuccessMessage += " permanently" } runner.Run() return nil }, }
View Source
var DeleteAliasesCmd = &cobra.Command{ Use: "aliases [flags] <email> [<email>...]", Aliases: []string{"alias"}, Short: "Deletes aliases", Long: "Deletes aliases. By default performs a soft delete. Use --permanent for hard delete.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") if flagPermanent && flagForce { return fmt.Errorf("cannot use --permanent and --force flags together") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Aliases(tx).Delete(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to delete alias", SuccessMessage: "Successfully deleted alias", } if flagPermanent { runner.SuccessMessage += " permanently" } runner.Run() return nil }, }
View Source
var DeleteCmd = &cobra.Command{
Use: "delete",
Short: "Delete mail system objects",
}
View Source
var DeleteDomainCatchallTargetsCmd = &cobra.Command{ Use: "catchall-targets [flags] <domain> <target-email> [<target-email>...]", Aliases: []string{"catchall-target", "catchalls", "catchall"}, Short: "Deletes catch-all targets from a domain", Long: "Deletes catch-all targets from a domain. By default performs a soft delete. Use --permanent for hard delete.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") if flagPermanent && flagForce { return fmt.Errorf("cannot use --permanent and --force flags together") } argDomain := args[0] argEmails := ParseEmailArgs(args[1:]) if len(argEmails) != len(args)-1 { return fmt.Errorf("invalid email arguments") } options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.DomainsCatchallTargets(tx).Delete(argDomain, item, options) }, ItemString: func(item utils.EmailAddress) string { return "@" + argDomain + " -> " + item.String() }, FailureMessage: "failed to delete catchall target", SuccessMessage: "Successfully deleted catchall target", } if flagPermanent { runner.SuccessMessage += " permanently" } runner.Run() return nil }, }
View Source
var DeleteDomainsCmd = &cobra.Command{ Use: "domains [flags] <fqdn> [<fqdn>...]", Aliases: []string{"domain"}, Short: "Deletes domains", Long: "Deletes domains. By default performs a soft delete. Use --permanent for hard delete.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") if flagPermanent && flagForce { return fmt.Errorf("cannot use --permanent and --force flags together") } argDomains := ParseDomainFQDNArgs(args) if len(argDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[string]{ Items: argDomains, Exec: func(tx *sql.Tx, item string) error { return db.Domains(tx).Delete(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to delete domain", SuccessMessage: "Successfully deleted domain", } if flagPermanent { runner.SuccessMessage += " permanently" } runner.Run() return nil }, }
View Source
var DeleteMailboxesCmd = &cobra.Command{ Use: "mailboxes [flags] <email> [<email>...]", Aliases: []string{"mailbox"}, Short: "Deletes mailboxes", Long: "Deletes mailboxes. By default performs a soft delete. Use --permanent for hard delete.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") if flagPermanent && flagForce { return fmt.Errorf("cannot use --permanent and --force flags together") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Mailboxes(tx).Delete(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to delete mailbox", SuccessMessage: "Successfully deleted mailbox", } if flagPermanent { runner.SuccessMessage += " permanently" } runner.Run() return nil }, }
View Source
var DeleteRecipientsRelayedCmd = &cobra.Command{ Use: "recipients-relayed [flags] <email> [<email>...]", Aliases: []string{"recipient-relayed", "relayed-recipients", "relayed-recipient", "relayed"}, Short: "Deletes relayed recipients", Long: "Deletes relayed recipients. By default performs a soft delete. Use --permanent for hard delete.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") if flagPermanent && flagForce { return fmt.Errorf("cannot use --permanent and --force flags together") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.RecipientsRelayed(tx).Delete(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to delete relayed recipient", SuccessMessage: "Successfully deleted relayed recipient", } if flagPermanent { runner.SuccessMessage += " permanently" } runner.Run() return nil }, }
View Source
var DeleteRemoteSendGrantsCmd = &cobra.Command{ Use: "send-grants <remote-name> <email> [<email>...]", Aliases: []string{"send-grant"}, Short: "Deletes send grants from a remote", Long: "Deletes send grants from a remote. By default performs a soft delete. Use --permanent --force for hard delete.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") if flagPermanent && flagForce { return fmt.Errorf("cannot use --permanent and --force flags together") } argRemoteName := args[0] argEmails := ParseEmailOrWildcardArgs(args[1:]) if len(argEmails) != len(args[1:]) { return fmt.Errorf("invalid email argument") } options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[utils.EmailAddressOrWildcard]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddressOrWildcard) error { return db.RemotesSendGrants(tx).Delete(argRemoteName, item, options) }, ItemString: func(item utils.EmailAddressOrWildcard) string { return argRemoteName + " -> " + item.String() }, FailureMessage: "failed to delete send grant", SuccessMessage: "Successfully deleted send grant", } runner.Run() return nil }, }
View Source
var DeleteRemotesCmd = &cobra.Command{ Use: "remotes [flags] <name> [<name>...]", Aliases: []string{"remote"}, Short: "Deletes remotes", Long: "Deletes remotes. By default performs a soft delete. Use --permanent for hard delete.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Remotes(tx).Delete(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to delete remote", SuccessMessage: "Successfully deleted remote", } runner.Run() return nil }, }
View Source
var DeleteTransportsCmd = &cobra.Command{ Use: "transports [flags] <name> [<name>...]", Aliases: []string{"transport"}, Short: "Deletes transports", Long: "Deletes transports. By default performs a soft delete. Use --permanent for hard delete.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPermanent, _ := cmd.Flags().GetBool("permanent") flagForce, _ := cmd.Flags().GetBool("force") options := db.DeleteOptions{ Permanent: flagPermanent, Force: flagForce, } runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Transports(tx).Delete(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to delete transport", SuccessMessage: "Successfully deleted transport", } if flagPermanent { runner.SuccessMessage += " permanently" } runner.Run() return nil }, }
View Source
var DescribeCmd = &cobra.Command{ Use: "describe", Short: "Describe mail system objects", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { dbConn, err := db.Connect() if err != nil { utils.PrintErrorWithMessage("failed to connect to database", err) return nil } defer func() { if err := dbConn.Close(); err != nil { utils.PrintErrorWithMessage("failed to close database connection", err) } }() if strings.Contains(args[0], "@") { emailOrWildcard, err := utils.ParseEmailAddressOrWildcard(args[0]) if err != nil { utils.PrintError(fmt.Errorf("failed to parse email: %w", err)) return nil } if emailOrWildcard.IsWildcard() { if described, err := describeDomainscatchalltargets(dbConn, emailOrWildcard.DomainFQDN); described || err != nil { if err != nil { utils.PrintError(err) } return nil } } else { email := utils.EmailAddress{ DomainFQDN: emailOrWildcard.DomainFQDN, LocalPart: *emailOrWildcard.LocalPart, } if described, err := describeAliases(dbConn, email); described || err != nil { if err != nil { utils.PrintError(err) } return nil } if described, err := DescribeCanonicalAddress(dbConn, email); described || err != nil { if err != nil { utils.PrintError(err) } return nil } if described, err := describeMailboxes(dbConn, email); described || err != nil { if err != nil { utils.PrintError(err) } return nil } if described, err := describeRecipientsrelayed(dbConn, email); described || err != nil { if err != nil { utils.PrintError(err) } return nil } } describeUnknownEmail(dbConn, emailOrWildcard) return nil } else { if described, err := describeDomains(dbConn, args[0]); described || err != nil { if err != nil { utils.PrintError(err) } return nil } if described, err := describeTransports(dbConn, args[0]); described || err != nil { if err != nil { utils.PrintError(err) } return nil } if described, err := describeRemotes(dbConn, args[0]); described || err != nil { if err != nil { utils.PrintError(err) } return nil } describeUnknown(dbConn, args[0]) return nil } }, }
View Source
var DisableAliasTargetsCmd = &cobra.Command{ Use: "alias-targets [flags] <alias-email> <target-email> [<target-email>...]", Aliases: []string{"alias-target", "targets", "target"}, Short: "Disables features on alias targets of an alias", Long: `Disable forwarding and/or sending on an alias target. Use flags to select which property to disable.`, Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { flagForward, _ := cmd.Flags().GetBool("forward") flagSend, _ := cmd.Flags().GetBool("send") if !flagForward && !flagSend { return fmt.Errorf("at least one of --forward or --send flags must be specified") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } argAliasEmail := argEmails[0] argTargetEmails := argEmails[1:] disabled := false options := db.AliasesTargetsPatchOptions{} if flagForward { options.ForwardingToTargetEnabled = &disabled } if flagSend { options.SendingFromTargetEnabled = &disabled } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argTargetEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.AliasesTargets(tx).Patch(argAliasEmail, item, options) }, ItemString: func(item utils.EmailAddress) string { return argAliasEmail.String() + " -> " + item.String() }, FailureMessage: "failed to disable alias target", SuccessMessage: "Successfully disable alias target", } runner.Run() return nil }, }
View Source
var DisableAliasesCmd = &cobra.Command{ Use: "aliases <email> [<email>...]", Aliases: []string{"alias"}, Short: "Disables aliases", Long: "Disables aliases.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } enabled := false options := db.AliasesPatchOptions{ Enabled: &enabled, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Aliases(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to disable alias", SuccessMessage: "Successfully disabled alias", } runner.Run() return nil }, }
View Source
var DisableCmd = &cobra.Command{
Use: "disable",
Short: "Disable mail system objects",
}
View Source
var DisableDomainCatchallTargetsCmd = &cobra.Command{ Use: "catchall-targets <domain> <target-email> [<target-email>...]", Aliases: []string{"catchall-target", "catchalls", "catchall"}, Short: "Disables forwarding on catch-all targets of a domain", Long: "Disables forwarding on catch-all targets of a domain.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argDomain := args[0] argEmails := ParseEmailArgs(args[1:]) if len(argEmails) != len(args)-1 { return fmt.Errorf("invalid email arguments") } enabled := false options := db.DomainsCatchallTargetsPatchOptions{ ForwardingToTargetEnabled: &enabled, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.DomainsCatchallTargets(tx).Patch(argDomain, item, options) }, ItemString: func(item utils.EmailAddress) string { return "@" + argDomain + " -> " + item.String() }, FailureMessage: "failed to disable catchall target", SuccessMessage: "Successfully disable catchall target", } runner.Run() return nil }, }
View Source
var DisableDomainsCmd = &cobra.Command{ Use: "domains <fqdn> [<fqdn>...]", Aliases: []string{"domain"}, Short: "Disables domains", Long: "Disables domains.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argDomains := ParseDomainFQDNArgs(args) if len(argDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } enabled := false options := db.DomainsPatchOptions{ Enabled: &enabled, } runner := db.TxForEachRunner[string]{ Items: argDomains, Exec: func(tx *sql.Tx, item string) error { return db.Domains(tx).Patch(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to disable domain", SuccessMessage: "Successfully disabled domain", } runner.Run() return nil }, }
View Source
var DisableMailboxesCmd = &cobra.Command{ Use: "mailboxes [flags] <email> [<email>...]", Aliases: []string{"mailbox"}, Short: "Disables features on mailboxes", Long: "Disables login, receiving, and/or sending for mailboxes. Use flags to select which property to disable.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagLogin, _ := cmd.Flags().GetBool("login") flagReceiving, _ := cmd.Flags().GetBool("receiving") flagSending, _ := cmd.Flags().GetBool("sending") if !flagLogin && !flagReceiving && !flagSending { return fmt.Errorf("at least one of --login, --receiving, or --sending must be true when specified") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } disabled := false options := db.MailboxesPatchOptions{} if flagLogin { options.Login = &disabled } if flagReceiving { options.Receiving = &disabled } if flagSending { options.Sending = &disabled } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Mailboxes(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to patch mailbox", SuccessMessage: "Successfully patched mailbox", } runner.Run() return nil }, }
View Source
var DisableRecipientsRelayedCmd = &cobra.Command{ Use: "recipients-relayed <email> [<email>...]", Aliases: []string{"recipient-relayed", "relayed-recipients", "relayed-recipient", "relayed"}, Short: "Disables relayed recipients", Long: "Disables relayed recipients.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } enabled := false options := db.RecipientsRelayedPatchOptions{ Enabled: &enabled, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.RecipientsRelayed(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to disable relayed recipient", SuccessMessage: "Successfully disabled relayed recipient", } runner.Run() return nil }, }
View Source
var DisableRemotesCmd = &cobra.Command{ Use: "remotes <name> [<name>...]", Short: "Disables remotes", Long: "Disables remotes.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { enabled := false options := db.RemotesPatchOptions{ Enabled: &enabled, } runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Remotes(tx).Patch(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to disable remote", SuccessMessage: "Successfully disabled remote", } runner.Run() return nil }, }
View Source
var EnableAliasTargetsCmd = &cobra.Command{ Use: "alias-targets [flags] <alias-email> <target-email> [<target-email>...]", Aliases: []string{"alias-target", "targets", "target"}, Short: "Enables features on alias targets of an alias", Long: `Enables forwarding and/or sending on an alias target. Use flags to select which property to enable.`, Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { flagForward, _ := cmd.Flags().GetBool("forward") flagSend, _ := cmd.Flags().GetBool("send") if !flagForward && !flagSend { return fmt.Errorf("at least one of --forward or --send flags must be specified") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } argAliasEmail := argEmails[0] argTargetEmails := argEmails[1:] enabled := true options := db.AliasesTargetsPatchOptions{} if flagForward { options.ForwardingToTargetEnabled = &enabled } if flagSend { options.SendingFromTargetEnabled = &enabled } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argTargetEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.AliasesTargets(tx).Patch(argAliasEmail, item, options) }, ItemString: func(item utils.EmailAddress) string { return argAliasEmail.String() + " -> " + item.String() }, FailureMessage: "failed to enable alias target", SuccessMessage: "Successfully enable alias target", } runner.Run() return nil }, }
View Source
var EnableAliasesCmd = &cobra.Command{ Use: "aliases <email> [<email>...]", Aliases: []string{"alias"}, Short: "Enables aliases", Long: "Enables aliases.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } enabled := true options := db.AliasesPatchOptions{ Enabled: &enabled, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Aliases(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to enable alias", SuccessMessage: "Successfully enabled alias", } runner.Run() return nil }, }
View Source
var EnableCmd = &cobra.Command{
Use: "enable",
Short: "Enable mail system objects",
}
View Source
var EnableDomainCatchallTargetsCmd = &cobra.Command{ Use: "catchall-targets <domain> <target-email> [<target-email>...]", Aliases: []string{"catchall-target", "catchalls", "catchall"}, Short: "Enables forwarding on catch-all targets of a domain", Long: "Enables forwarding on catch-all targets of a domain.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argDomain := args[0] argEmails := ParseEmailArgs(args[1:]) if len(argEmails) != len(args)-1 { return fmt.Errorf("invalid email arguments") } enabled := true options := db.DomainsCatchallTargetsPatchOptions{ ForwardingToTargetEnabled: &enabled, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.DomainsCatchallTargets(tx).Patch(argDomain, item, options) }, ItemString: func(item utils.EmailAddress) string { return "@" + argDomain + " -> " + item.String() }, FailureMessage: "failed to enable catchall target", SuccessMessage: "Successfully enabled catchall target", } runner.Run() return nil }, }
View Source
var EnableDomainsCmd = &cobra.Command{ Use: "domains <fqdn> [<fqdn>...]", Aliases: []string{"domain"}, Short: "Enables domains", Long: "Enables domains.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argDomains := ParseDomainFQDNArgs(args) if len(argDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } enabled := true options := db.DomainsPatchOptions{ Enabled: &enabled, } runner := db.TxForEachRunner[string]{ Items: argDomains, Exec: func(tx *sql.Tx, item string) error { return db.Domains(tx).Patch(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to enable domain", SuccessMessage: "Successfully enabled domain", } runner.Run() return nil }, }
View Source
var EnableMailboxesCmd = &cobra.Command{ Use: "mailboxes [flags] <email> [<email>...]", Aliases: []string{"mailbox"}, Short: "Enables features on mailboxes", Long: "Enables login, receiving, and/or sending for mailboxes. Use flags to select which property to disable.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagLogin, _ := cmd.Flags().GetBool("login") flagReceiving, _ := cmd.Flags().GetBool("receiving") flagSending, _ := cmd.Flags().GetBool("sending") if !flagLogin && !flagReceiving && !flagSending { return fmt.Errorf("at least one of --login, --receiving, or --sending must be true when specified") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } enabled := true options := db.MailboxesPatchOptions{} if flagLogin { options.Login = &enabled } if flagReceiving { options.Receiving = &enabled } if flagSending { options.Sending = &enabled } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Mailboxes(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to enable mailbox", SuccessMessage: "Successfully enabled mailbox", } runner.Run() return nil }, }
View Source
var EnableRecipientsRelayedCmd = &cobra.Command{ Use: "recipients-relayed <email> [<email>...]", Aliases: []string{"recipient-relayed", "relayed-recipients", "relayed-recipient", "relayed"}, Short: "Enables relayed recipients", Long: "Enables relayed recipients.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } enabled := true options := db.RecipientsRelayedPatchOptions{ Enabled: &enabled, } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.RecipientsRelayed(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to enable relayed recipient", SuccessMessage: "Successfully enabled relayed recipient", } runner.Run() return nil }, }
View Source
var EnableRemotesCmd = &cobra.Command{ Use: "remotes <name> [<name>...]", Aliases: []string{"remote"}, Short: "Enables remotes", Long: "Enables remotes.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { enabled := true options := db.RemotesPatchOptions{ Enabled: &enabled, } runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Remotes(tx).Patch(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to enable remote", SuccessMessage: "Successfully enabled remote", } runner.Run() return nil }, }
View Source
var (
ErrNoValueProvided = errors.New("no value provided")
)
View Source
var ListAliasTargetsCmd = &cobra.Command{ Use: "alias-targets [flags] [<alias-email>...]", Aliases: []string{"alias-target", "targets", "target"}, Short: "List alias targets", Long: "List alias targets. If aliases are provided, only targets for these aliases are listed.", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") var filterEmails []utils.EmailAddress if len(args) > 0 { filterEmails = ParseEmailArgs(args) if len(filterEmails) != len(args) { return fmt.Errorf("invalid email arguments") } } targets, err := listAliasTargets(db.AliasesTargetsListOptions{ FilterAliasEmails: filterEmails, IncludeDeleted: flagDeleted, IncludeAll: flagAll, }) if err != nil { return nil } if len(targets) == 0 { fmt.Println("No targets found") return nil } if flagJSON { output, err := json.MarshalIndent(targets, "", " ") if err != nil { utils.PrintErrorWithMessage("Failed to marshal targets", err) return nil } fmt.Println(string(output)) return nil } headers := []string{"Alias", "Target", "Foreign", "Forward", "Send"} if flagVerbose { headers = append(headers, "Created", "Updated") } if flagAll || flagDeleted { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). StyleFunc(func(row, col int) lipgloss.Style { if row == table.HeaderRow { return utils.TableHeaderStyle } cellStyle := utils.TableRowStyle switch col { case 2, 3, 4: cellStyle = cellStyle.Align(lipgloss.Center) } return cellStyle }). Headers(headers...) for _, target := range targets { row := []string{ target.AliasEmail, target.TargetEmail, utils.MaybeEnabledTableStyle.Render(target.IsForeign), utils.MaybeEnabledTableStyle.Render(target.ForwardingToTargetEnabled, target.AliasEnabled, target.DomainEnabled), utils.MaybeEnabledTableStyle.Render(target.SendingFromTargetEnabled, target.AliasEnabled, target.DomainEnabled), } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(target.CreatedAt), utils.MaybeTimeStyle.Render(target.UpdatedAt), ) } if flagAll || flagDeleted { row = append(row, utils.MaybeTimeStyle.Render(target.DeletedAt), ) } t.Row(row...) } fmt.Println(t) return nil }, }
View Source
var ListAliasesCmd = &cobra.Command{ Use: "aliases [flags] [<domain>...]", Aliases: []string{"alias"}, Short: "List aliases", Long: "List aliases. If domains are provided, only aliases for these domains are listed.", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") if flagDeleted && flagAll { return fmt.Errorf("cannot use --deleted and --all flags together") } filterDomains := ParseDomainFQDNArgs(args) if len(filterDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } aliases, err := listAliases(db.AliasesListOptions{ FilterDomains: filterDomains, IncludeDeleted: flagDeleted, IncludeAll: flagAll, }) if err != nil { return nil } if flagJSON { json, err := json.Marshal(aliases) if err != nil { utils.PrintErrorWithMessage("Failed to marshal aliases to JSON", err) } fmt.Println(string(json)) return nil } headers := []string{"Domain", "Name", "Enabled", "Targets"} if flagVerbose { headers = append(headers, "Created", "Last Updated") } if flagDeleted || flagAll { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). StyleFunc(func(row, col int) lipgloss.Style { cellStyle := utils.TableRowStyle if row == table.HeaderRow { cellStyle = utils.TableHeaderStyle } switch col { case 2: return cellStyle.Align(lipgloss.Center) case 3: return cellStyle.Align(lipgloss.Right) default: return cellStyle.Align(lipgloss.Left) } }). Headers(headers...) for _, a := range aliases { row := []string{ a.DomainFQDN, utils.MaybeWildcardNameStyle.Render(a.Name), utils.MaybeEnabledTableStyle.Render(a.Enabled, a.DomainEnabled), utils.MaybeZeroStyle.Render(a.TargetCount), } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(a.CreatedAt), utils.MaybeTimeStyle.Render(a.UpdatedAt), ) } if flagDeleted || flagAll { row = append(row, utils.MaybeTimeStyle.Render(a.DeletedAt), ) } t.Row(row...) } fmt.Println(t.Render()) return nil }, }
View Source
var ListCmd = &cobra.Command{
Use: "list",
Short: "List mail system objects",
}
View Source
var ListDomainCatchallTargetsCmd = &cobra.Command{ Use: "catchall-targets [flags] [<domain>...]", Aliases: []string{"catchall-target", "catchalls", "catchall"}, Short: "List catch-all targets.", Long: "List catch-all targets. If domains are provided, only catch-all targets for these domains are listed.", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") argDomains := args options := db.DomainsCatchallTargetsListOptions{ FilterDomains: argDomains, IncludeDeleted: flagDeleted, IncludeAll: flagAll, } targets, err := listCatchallTargets(options) if err != nil { return nil } if len(targets) == 0 { fmt.Println("No catchall targets found for this domain") return nil } if flagJSON { out, err := json.MarshalIndent(targets, "", " ") if err != nil { utils.PrintErrorWithMessage("Failed to marshal targets", err) return nil } fmt.Println(string(out)) return nil } headers := []string{"Domain", "Target", "Forward", "Fallback Only"} if flagVerbose { headers = append(headers, "Created", "Updated") } if flagAll || flagDeleted { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). StyleFunc(func(row, col int) lipgloss.Style { if row == table.HeaderRow { return utils.TableHeaderStyle } cellStyle := utils.TableRowStyle if col == 2 || col == 3 { cellStyle = cellStyle.Align(lipgloss.Center) } return cellStyle }). Headers(headers...) for _, tgt := range targets { row := []string{ tgt.DomainFQDN, tgt.TargetEmail, utils.MaybeEnabledTableStyle.Render(tgt.ForwardingToTargetEnabled), utils.MaybeEnabledTableStyle.Render(tgt.FallbackOnly), } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(tgt.CreatedAt), utils.MaybeTimeStyle.Render(tgt.UpdatedAt)) } if flagAll || flagDeleted { row = append(row, utils.MaybeTimeStyle.Render(tgt.DeletedAt)) } t.Row(row...) } fmt.Println(t) return nil }, }
View Source
var ListDomainsCmd = &cobra.Command{ Use: "domains [flags]", Aliases: []string{"domain"}, Short: "List domains", Long: "List domains.", Args: cobra.MinimumNArgs(0), RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") if flagDeleted && flagAll { return fmt.Errorf("cannot use --deleted and --all flags together") } options := db.DomainsListOptions{ IncludeDeleted: flagDeleted, IncludeAll: flagAll, } domains, err := listDomains(options) if err != nil { return nil } if flagJSON { jsonData, err := json.Marshal(domains) if err != nil { utils.PrintErrorWithMessage("failed to marshal domains to JSON", err) return nil } fmt.Println(string(jsonData)) return nil } headers := []string{"FQDN", "Type", "Enabled", "Transport / Target Domain"} if flagVerbose { headers = append(headers, "Created", "Last Updated") } if flagDeleted || flagAll { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). StyleFunc(func(row, col int) lipgloss.Style { cellStyle := utils.TableRowStyle if row == table.HeaderRow { cellStyle = utils.TableHeaderStyle } switch col { case 2: return cellStyle.Align(lipgloss.Center) default: return cellStyle.Align(lipgloss.Left) } }). Headers(headers...) for _, domain := range domains { row := []string{ domain.FQDN, domain.Type, } switch domain.Type { case "canonical": row = append(row, utils.MaybeEnabledTableStyle.Render(domain.Enabled, domain.TargetDomainEnabled), utils.MaybeEmptyStyle.Render(domain.TargetDomainFQDN), ) case "alias": row = append(row, utils.MaybeEnabledTableStyle.Render(domain.Enabled), utils.BlackStyle.Render("-"), ) default: row = append(row, utils.MaybeEnabledTableStyle.Render(domain.Enabled), utils.MaybeIDSuffixStyle.Render(domain.Transport, domain.TransportName), ) } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(domain.CreatedAt), utils.MaybeTimeStyle.Render(domain.UpdatedAt), ) } if flagDeleted || flagAll { row = append(row, utils.MaybeTimeStyle.Render(domain.DeletedAt), ) } t.Row(row...) } fmt.Println(t.Render()) return nil }, }
View Source
var ListMailboxesCmd = &cobra.Command{ Use: "mailboxes [flags] [<domain>...]", Aliases: []string{"mailbox"}, Short: "List mailboxes", Long: "List mailboxes.\nIf domains are provided, only mailboxes for these domains are listed.", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") if flagDeleted && flagAll { return fmt.Errorf("cannot use --deleted and --all flags together") } filterDomains := ParseDomainFQDNArgs(args) if len(filterDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } options := db.MailboxesListOptions{ FilterDomains: filterDomains, IncludeDeleted: flagDeleted, IncludeAll: flagAll, } mailboxes, err := listMailboxes(options) if err != nil { return nil } if flagJSON { out, err := json.Marshal(mailboxes) if err != nil { utils.PrintErrorWithMessage("Failed to marshal mailboxes to JSON", err) return nil } fmt.Println(string(out)) return nil } headers := []string{"Domain", "Name", "Login", "Receive", "Send", "Pwd", "Quota", "Transport"} if flagVerbose { headers = append(headers, "Created", "Last Updated") } if flagDeleted || flagAll { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). StyleFunc(func(row, col int) lipgloss.Style { cellStyle := utils.TableRowStyle if row == table.HeaderRow { cellStyle = utils.TableHeaderStyle } switch col { case 2, 3, 4, 5: return cellStyle.Align(lipgloss.Center) case 6: return cellStyle.Align(lipgloss.Right) default: return cellStyle.Align(lipgloss.Left) } }). Headers(headers...) for _, m := range mailboxes { row := []string{ m.DomainFQDN, m.Name, utils.MaybeEnabledTableStyle.Render(m.LoginEnabled, m.DomainEnabled), utils.MaybeEnabledTableStyle.Render(m.ReceivingEnabled, m.DomainEnabled), utils.MaybeEnabledTableStyle.Render(m.SendingEnabled, m.DomainEnabled), utils.MaybePasswordStyle.Render(m.PasswordSet), utils.MaybeQuotaStyle.Render(m.StorageQuota, 1024*1024), utils.MaybeIDSuffixStyle.Render(m.Transport, m.TransportName), } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(m.CreatedAt), utils.MaybeTimeStyle.Render(m.UpdatedAt), ) } if flagDeleted || flagAll { row = append(row, utils.MaybeTimeStyle.Render(m.DeletedAt), ) } t.Row(row...) } fmt.Println(t.Render()) return nil }, }
View Source
var ListRecipientsRelayedCmd = &cobra.Command{ Use: "relayed-recipients [flags] [<domain>...]", Aliases: []string{"recipient-relayed", "relayed-recipients", "relayed-recipient", "relayed"}, Short: "List relayed recipients", Long: "List relayed recipients.\nIf domains are provided, only recipients for these domains are listed.", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") if flagDeleted && flagAll { return fmt.Errorf("cannot use --deleted and --all flags together") } filterDomains := ParseDomainFQDNArgs(args) if len(filterDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } options := db.RecipientsRelayedListOptions{ FilterDomains: filterDomains, IncludeDeleted: flagDeleted, IncludeAll: flagAll, } recipients, err := listRelayedRecipients(options) if err != nil { return nil } if flagJSON { out, err := json.Marshal(recipients) if err != nil { utils.PrintErrorWithMessage("Failed to marshal recipients to JSON", err) return nil } fmt.Println(string(out)) return nil } if len(recipients) == 0 { fmt.Println("No relayed recipients found") return nil } headers := []string{"Domain", "Name", "Enabled"} if flagVerbose { headers = append(headers, "Created", "Last Updated") } if flagDeleted || flagAll { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). StyleFunc(func(row, col int) lipgloss.Style { cellStyle := utils.TableRowStyle if row == table.HeaderRow { cellStyle = utils.TableHeaderStyle } switch col { case 2: return cellStyle.Align(lipgloss.Center) default: return cellStyle.Align(lipgloss.Left) } }). Headers(headers...) for _, r := range recipients { row := []string{ r.DomainFQDN, r.Name, utils.MaybeEnabledTableStyle.Render(r.Enabled, r.DomainEnabled), } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(r.CreatedAt), utils.MaybeTimeStyle.Render(r.UpdatedAt), ) } if flagDeleted || flagAll { row = append(row, utils.MaybeTimeStyle.Render(r.DeletedAt), ) } t.Row(row...) } fmt.Println(t.Render()) return nil }, }
View Source
var ListRemoteSendGrantsCmd = &cobra.Command{ Use: "send-grants [flags] [<remote-name>...]", Aliases: []string{"send-grant"}, Short: "List send grants for remotes", Long: "List send grants for remotes.\nIf remote names are provided, only send grants for these remotes are listed.", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") if flagDeleted && flagAll { return fmt.Errorf("cannot use --deleted and --all flags together") } var filterNames []string if len(args) > 0 { filterNames = args } grants, err := listGrants(db.RemotesSendGrantsListOptions{ FilterRemoteNames: filterNames, IncludeDeleted: flagDeleted, IncludeAll: flagAll, }) if err != nil { return nil } if flagJSON { out, err := json.Marshal(grants) if err != nil { utils.PrintErrorWithMessage("Failed to marshal send grants to JSON", err) return nil } fmt.Println(string(out)) return nil } if len(grants) == 0 { fmt.Println("No send grants found") return nil } headers := []string{"Remote", "Domain", "Name"} if flagVerbose { headers = append(headers, "Created", "Last Updated") } if flagDeleted || flagAll { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). StyleFunc(func(row, col int) lipgloss.Style { cellStyle := utils.TableRowStyle if row == table.HeaderRow { cellStyle = utils.TableHeaderStyle } switch col { default: return cellStyle.Align(lipgloss.Left) } }). Headers(headers...) for _, g := range grants { row := []string{ g.RemoteName, g.DomainFQDN, utils.SQLLikeStyle.Render(g.Name), } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(g.CreatedAt), utils.MaybeTimeStyle.Render(g.UpdatedAt), ) } if flagDeleted || flagAll { row = append(row, utils.MaybeTimeStyle.Render(g.DeletedAt), ) } t.Row(row...) } fmt.Println(t.Render()) return nil }, }
View Source
var ListRemotesCmd = &cobra.Command{ Use: "remotes [flags]", Short: "List remotes", Long: "List remotes.", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") if flagDeleted && flagAll { return fmt.Errorf("cannot use --deleted and --all flags together") } options := db.RemotesListOptions{ IncludeDeleted: flagDeleted, IncludeAll: flagAll, } remotes, err := listRemotes(options) if err != nil { return nil } if flagJSON { out, err := json.Marshal(remotes) if err != nil { utils.PrintErrorWithMessage("Failed to marshal remotes to JSON", err) return nil } fmt.Println(string(out)) return nil } if len(remotes) == 0 { fmt.Println("No remotes found") return nil } headers := []string{"Name", "Enabled", "Pwd"} if flagVerbose { headers = append(headers, "Created", "Last Updated") } if flagDeleted || flagAll { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). StyleFunc(func(row, col int) lipgloss.Style { cellStyle := utils.TableRowStyle if row == table.HeaderRow { cellStyle = utils.TableHeaderStyle } switch col { case 1, 2: return cellStyle.Align(lipgloss.Center) default: return cellStyle.Align(lipgloss.Left) } }). Headers(headers...) for _, r := range remotes { row := []string{ r.Name, utils.MaybeEnabledTableStyle.Render(r.Enabled), utils.MaybePasswordStyle.Render(r.PasswordSet), } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(r.CreatedAt), utils.MaybeTimeStyle.Render(r.UpdatedAt), ) } if flagDeleted || flagAll { row = append(row, utils.MaybeTimeStyle.Render(r.DeletedAt), ) } t.Row(row...) } fmt.Println(t.Render()) return nil }, }
View Source
var ListTransportsCmd = &cobra.Command{ Use: "transports [flags]", Short: "List transports", Long: "List all transports. Use --deleted to show only deleted transports, --all to show both active and deleted.", RunE: func(cmd *cobra.Command, args []string) error { flagDeleted, _ := cmd.Flags().GetBool("deleted") flagAll, _ := cmd.Flags().GetBool("all") flagJSON, _ := cmd.Flags().GetBool("json") flagVerbose, _ := cmd.Flags().GetBool("verbose") transports, err := listTransports(db.TransportsListOptions{IncludeDeleted: flagDeleted, IncludeAll: flagAll}) if err != nil { return nil } if flagJSON { encoder := json.NewEncoder(os.Stdout) if err := encoder.Encode(transports); err != nil { utils.PrintErrorWithMessage("Failed to encode JSON", err) return nil } return nil } headers := []string{"Name", "Method", "Host", "Port", "MX Lookup"} if flagVerbose { headers = append(headers, "Created", "Last Updated") } if flagDeleted || flagAll { headers = append(headers, "Deleted") } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(utils.BlackStyle). Headers(headers...). StyleFunc(func(row, col int) lipgloss.Style { if row == table.HeaderRow { return utils.TableHeaderStyle } cellStyle := utils.TableRowStyle switch col { case 3: return cellStyle.Align(lipgloss.Right) case 4: return cellStyle.Align(lipgloss.Center) } return cellStyle }) mxLookupStyle := utils.MaybeEnabledTableStyle mxLookupStyle.TrueStyle = utils.BlueStyle.Bold(true) mxLookupStyle.FalseStyle = utils.BlackStyle.Bold(true) for _, transport := range transports { row := []string{ transport.Name, transport.Method, transport.Host, utils.MaybeEmptyStyle.Render(transport.Port), mxLookupStyle.Render(transport.MXLookup), } if flagVerbose { row = append(row, utils.MaybeTimeStyle.Render(transport.CreatedAt), utils.MaybeTimeStyle.Render(transport.UpdatedAt), ) } if flagAll || flagDeleted { row = append(row, utils.MaybeTimeStyle.Render(transport.DeletedAt), ) } t.Row(row...) } fmt.Println(t.Render()) return nil }, }
View Source
var PatchAliasTargetsCmd = &cobra.Command{ Use: "alias-targets [flags] <email> [<email>...]", Aliases: []string{"alias-target", "targets", "target"}, Short: "Updates existing alias targets", Long: "Updates specified properties for existing alias targets.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { if !cmd.Flags().Changed("forward") && !cmd.Flags().Changed("send") { return fmt.Errorf("at least one of --forward or --send flags must be specified") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } argAliasEmail := argEmails[0] argTargetEmails := argEmails[1:] options := db.AliasesTargetsPatchOptions{} if cmd.Flags().Changed("forward") { flagForward, _ := cmd.Flags().GetBool("forward") options.ForwardingToTargetEnabled = &flagForward } if cmd.Flags().Changed("send") { flagSend, _ := cmd.Flags().GetBool("send") options.SendingFromTargetEnabled = &flagSend } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argTargetEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.AliasesTargets(tx).Patch(argAliasEmail, item, options) }, ItemString: func(item utils.EmailAddress) string { return argAliasEmail.String() + " -> " + item.String() }, FailureMessage: "failed to patch alias target", SuccessMessage: "Successfully patch alias target", } runner.Run() return nil }, }
View Source
var PatchAliasesCmd = &cobra.Command{ Use: "aliases [flags] <email> [<email>...]", Aliases: []string{"alias"}, Short: "Updates existing aliases", Long: "Updates specified properties of existing aliases.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagEnabled, _ := cmd.Flags().GetBool("enabled") if !cmd.Flags().Changed("enabled") { return fmt.Errorf("no changes specified") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.AliasesPatchOptions{} if cmd.Flags().Changed("enabled") { options.Enabled = &flagEnabled } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Aliases(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to patch alias", SuccessMessage: "Successfully patched alias", } runner.Run() return nil }, }
View Source
var PatchCmd = &cobra.Command{
Use: "patch",
Short: "Patch mail system objects",
}
View Source
var PatchDomainCatchallTargetsCmd = &cobra.Command{ Use: "catchall-targets [flags] <domain> <target> [<target>...]", Aliases: []string{"catchall-target", "catchalls", "catchall"}, Short: "Updates existing catchall targets", Long: "Updates specified properties for existing catchall targets.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { if !cmd.Flags().Changed("forward") && !cmd.Flags().Changed("fallback-only") { return fmt.Errorf("at least one of --forward or --fallback-only flags must be specified") } argDomain := args[0] argEmails := ParseEmailArgs(args[1:]) if len(argEmails) != len(args)-1 { return fmt.Errorf("invalid email arguments") } options := db.DomainsCatchallTargetsPatchOptions{} if cmd.Flags().Changed("forward") { flagForward, _ := cmd.Flags().GetBool("forward") options.ForwardingToTargetEnabled = &flagForward } if cmd.Flags().Changed("fallback-only") { flagOnly, _ := cmd.Flags().GetBool("fallback-only") options.FallbackOnly = &flagOnly } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.DomainsCatchallTargets(tx).Patch(argDomain, item, options) }, ItemString: func(item utils.EmailAddress) string { return "@" + argDomain + " -> " + item.String() }, FailureMessage: "failed to patch catchall target", SuccessMessage: "Successfully patched catchall target", } runner.Run() return nil }, }
View Source
var PatchDomainsCmd = &cobra.Command{ Use: "domains [flags] <fqdn> [<fqdn>...]", Aliases: []string{"domain"}, Short: "Updates existing domains", Long: "Updates specified properties for existing domains.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagEnabled, _ := cmd.Flags().GetBool("enabled") flagTransport, _ := cmd.Flags().GetString("transport") flagTargetDomain, _ := cmd.Flags().GetString("target-domain") if !cmd.Flags().Changed("enabled") && !cmd.Flags().Changed("transport") && !cmd.Flags().Changed("target-domain") { return fmt.Errorf("no changes specified") } argDomains := ParseDomainFQDNArgs(args) if len(argDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } var options db.DomainsPatchOptions if cmd.Flags().Changed("enabled") { options.Enabled = &flagEnabled } if cmd.Flags().Changed("transport") { options.TransportName = &flagTransport } if cmd.Flags().Changed("target-domain") { options.TargetDomainFQDN = &flagTargetDomain } runner := db.TxForEachRunner[string]{ Items: argDomains, Exec: func(tx *sql.Tx, item string) error { return db.Domains(tx).Patch(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to patch domain", SuccessMessage: "Successfully patched domain", } runner.Run() return nil }, }
View Source
var PatchMailboxesCmd = &cobra.Command{ Use: "mailboxes [flags] <email> [<email>...]", Aliases: []string{"mailbox"}, Short: "Updates existing mailboxes", Long: "Updates specified properties for existing mailboxes.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagPassword, _ := cmd.Flags().GetBool("password") flagPasswordStdin, _ := cmd.Flags().GetBool("password-stdin") flagPasswordMethod, _ := cmd.Flags().GetString("password-method") flagPasswordHashOptions, _ := cmd.Flags().GetString("password-hash-options") flagPasswordNo, _ := cmd.Flags().GetBool("no-password") if (flagPassword || flagPasswordStdin) && flagPasswordNo { return fmt.Errorf("cannot use --no-password with --password or --password-stdin") } if flagPassword && flagPasswordStdin { return fmt.Errorf("cannot use both --password and --password-stdin") } if len(args) > 1 && (flagPassword || flagPasswordStdin) { return fmt.Errorf("cannot set password while updating multiple mailboxes") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.MailboxesPatchOptions{} if flagPassword || flagPasswordStdin { passwordHash, err := ReadPasswordHashed(flagPasswordMethod, flagPasswordHashOptions, flagPasswordStdin) if err != nil { utils.PrintErrorWithMessage("failed to read password", err) return nil } options.PasswordHash = &sql.NullString{Valid: true, String: passwordHash} } if flagPasswordNo { options.PasswordHash = &sql.NullString{Valid: false} } if cmd.Flags().Changed("quota") { q, _ := cmd.Flags().GetInt32("quota") if q <= 0 { options.Quota = &sql.NullInt32{Valid: false} } else { options.Quota = &sql.NullInt32{Valid: true, Int32: q} } } if cmd.Flags().Changed("transport") { transportName, _ := cmd.Flags().GetString("transport") if transportName == "-" { options.TransportName = &sql.NullString{Valid: false} } else { options.TransportName = &sql.NullString{Valid: true, String: transportName} } } if cmd.Flags().Changed("login") { v, _ := cmd.Flags().GetBool("login") options.Login = &v } if cmd.Flags().Changed("receiving") { v, _ := cmd.Flags().GetBool("receiving") options.Receiving = &v } if cmd.Flags().Changed("sending") { v, _ := cmd.Flags().GetBool("sending") options.Sending = &v } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Mailboxes(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to patch mailbox", SuccessMessage: "Successfully patched mailbox", } runner.Run() return nil }, }
View Source
var PatchRecipientsRelayedCmd = &cobra.Command{ Use: "recipients-relayed [flags] <email> [<email>...]", Aliases: []string{"recipient-relayed", "relayed-recipients", "relayed-recipient", "relayed"}, Short: "Updates existing relayed recipients", Long: "Updates specified properties for existing relayed recipients. Emails must be in the format \"name@example.com\".", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagEnabled, _ := cmd.Flags().GetBool("enabled") if !cmd.Flags().Changed("enabled") { return fmt.Errorf("no changes specified") } argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } options := db.RecipientsRelayedPatchOptions{} if cmd.Flags().Changed("enabled") { options.Enabled = &flagEnabled } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.RecipientsRelayed(tx).Patch(item, options) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to patch relayed recipient", SuccessMessage: "Successfully patched relayed recipient", } runner.Run() return nil }, }
View Source
var PatchRemotesCmd = &cobra.Command{ Use: "remotes [flags] <hostname> [<hostname>...]", Short: "Updates existing remotes", Long: "Updates specified properties for existing remotes.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagEnabled, _ := cmd.Flags().GetBool("enabled") flagPassword, _ := cmd.Flags().GetBool("password") flagPasswordStdin, _ := cmd.Flags().GetBool("password-stdin") flagPasswordMethod, _ := cmd.Flags().GetString("password-method") flagPasswordHashOptions, _ := cmd.Flags().GetString("password-hash-options") flagPasswordNo, _ := cmd.Flags().GetBool("no-password") if (flagPassword || flagPasswordStdin) && flagPasswordNo { return fmt.Errorf("cannot use --no-password with --password or --password-stdin") } if flagPassword && flagPasswordStdin { return fmt.Errorf("cannot use both --password and --password-stdin") } if len(args) > 1 && (flagPassword || flagPasswordStdin) { return fmt.Errorf("cannot set password while updating multiple remotes") } if !flagPassword && !flagPasswordStdin && !flagPasswordNo && !cmd.Flags().Changed("enabled") { return fmt.Errorf("no changes specified. Use --password, --no-password, or --enabled flags") } options := db.RemotesPatchOptions{} if cmd.Flags().Changed("enabled") { options.Enabled = &flagEnabled } if flagPassword || flagPasswordStdin { passwordHash, err := ReadPasswordHashed(flagPasswordMethod, flagPasswordHashOptions, flagPasswordStdin) if err != nil { utils.PrintErrorWithMessage("failed to read password", err) return nil } options.PasswordHash = &sql.NullString{ String: passwordHash, Valid: true, } } if flagPasswordNo { options.PasswordHash = &sql.NullString{ Valid: false, } } runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Remotes(tx).Patch(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to patch remote", SuccessMessage: "Successfully patched remote", } runner.Run() return nil }, }
View Source
var PatchTransportsCmd = &cobra.Command{ Use: "transports [flags] <name> [<name>...]", Aliases: []string{"transport"}, Short: "Updates existing transports", Long: "Updates specified properties of an existing transport.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagMethod, _ := cmd.Flags().GetString("method") flagHost, _ := cmd.Flags().GetString("host") flagPort, _ := cmd.Flags().GetUint16("port") flagMxLookup, _ := cmd.Flags().GetBool("mx-lookup") if !cmd.Flags().Changed("method") && !cmd.Flags().Changed("host") && !cmd.Flags().Changed("port") && !cmd.Flags().Changed("mx-lookup") { return fmt.Errorf("no changes specified") } options := db.TransportsPatchOptions{} if cmd.Flags().Changed("method") { options.Method = &flagMethod } if cmd.Flags().Changed("host") { options.Host = &flagHost } if cmd.Flags().Changed("port") { if flagPort > 0 { options.Port = &sql.NullInt32{Int32: int32(flagPort), Valid: true} } else { options.Port = &sql.NullInt32{Valid: false} } } if cmd.Flags().Changed("mx-lookup") { options.MxLookup = &flagMxLookup } runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Transports(tx).Patch(item, options) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to patch transport", SuccessMessage: "Successfully patched transport", } runner.Run() return nil }, }
View Source
var RenameAliasesCmd = &cobra.Command{ Use: "alias <email> <new-email>", Aliases: []string{"aliases"}, Short: "Renames an alias", Long: "Renames an alias by changing its email address. This also supports changing the domain without loosing any of the targets or other relations.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } argOldEmail := argEmails[0] argNewEmail := argEmails[1] runner := db.TxRunner{ Exec: func(tx *sql.Tx) error { return db.Aliases(tx).Rename(argOldEmail, argNewEmail) }, ItemString: fmt.Sprintf("%s -> %s", argOldEmail.String(), argNewEmail.String()), FailureMessage: "failed to rename alias", SuccessMessage: "Successfully renamed alias", } runner.Run() return nil }, }
View Source
var RenameCmd = &cobra.Command{
Use: "rename",
Short: "Rename mail system objects",
}
View Source
var RenameDomainsCmd = &cobra.Command{ Use: "domain <old-fqdn> <new-fqdn>", Aliases: []string{"domains"}, Short: "Renames a domain", Long: "Renames a domain by changing its FQDN. All contained mailboxes, aliases, recipients, and other relations will be renamed too.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argDomains := ParseDomainFQDNArgs(args) if len(argDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } oldDomain := argDomains[0] newDomain := argDomains[1] runner := db.TxRunner{ Exec: func(tx *sql.Tx) error { return db.Domains(tx).Rename(oldDomain, newDomain) }, ItemString: fmt.Sprintf("%s -> %s", oldDomain, newDomain), FailureMessage: "failed to rename domain", SuccessMessage: "Successfully renamed domain", } runner.Run() return nil }, }
View Source
var RenameMailboxesCmd = &cobra.Command{ Use: "mailbox <email> <new-email>", Aliases: []string{"mailboxes"}, Short: "Renames a mailbox", Long: "Renames a mailbox. This also supports changing the domain without loosing any of the aliases, or other relations.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } oldEmail := argEmails[0] newEmail := argEmails[1] runner := db.TxRunner{ Exec: func(tx *sql.Tx) error { return db.Mailboxes(tx).Rename(oldEmail, newEmail) }, ItemString: fmt.Sprintf("%s -> %s", oldEmail, newEmail), FailureMessage: "failed to rename mailbox", SuccessMessage: "Successfully renamed mailbox", } runner.Run() return nil }, }
View Source
var RenameRecipientsRelayedCmd = &cobra.Command{ Use: "recipient-relayed <email> <new-email>", Aliases: []string{"recipients-relayed", "relayed-recipients", "relayed-recipient", "relayed"}, Short: "Renames a relayed recipient", Long: "Renames a relayed recipient. This also supports changing the domain without loosing any of the relations.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } oldEmail := argEmails[0] newEmail := argEmails[1] runner := db.TxRunner{ Exec: func(tx *sql.Tx) error { return db.RecipientsRelayed(tx).Rename(oldEmail, newEmail) }, ItemString: fmt.Sprintf("%s -> %s", oldEmail.String(), newEmail.String()), FailureMessage: "failed to rename relayed recipient", SuccessMessage: "Successfully renamed relayed recipient", } runner.Run() return nil }, }
View Source
var RenameRemotesCmd = &cobra.Command{ Use: "remote <old-name> <new-name>", Short: "Renames a remote", Long: "Renames a remote by changing its name.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { oldName := args[0] newName := args[1] runner := db.TxRunner{ Exec: func(tx *sql.Tx) error { return db.Remotes(tx).Rename(oldName, newName) }, ItemString: fmt.Sprintf("%s -> %s", oldName, newName), FailureMessage: "failed to rename remote", SuccessMessage: "Successfully renamed remote", } runner.Run() return nil }, }
View Source
var RenameTransportsCmd = &cobra.Command{ Use: "transport <old-name> <new-name>", Aliases: []string{"transports"}, Short: "Renames a transport", Long: "Renames a transport by changing its name.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { oldName := args[0] newName := args[1] runner := db.TxRunner{ Exec: func(tx *sql.Tx) error { return db.Transports(tx).Rename(oldName, newName) }, ItemString: fmt.Sprintf("%s -> %s", oldName, newName), FailureMessage: "failed to rename transport", SuccessMessage: "Successfully renamed transport", } runner.Run() return nil }, }
View Source
var RestoreAliasTargetsCmd = &cobra.Command{ Use: "alias-targets <alias-email> <target-email> [<target-email>...]", Aliases: []string{"alias-target", "targets", "target"}, Short: "Restores soft-deleted alias targets", Long: "Restore soft-deleted targets to an alias.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } argAliasEmail := argEmails[0] argTargetEmails := argEmails[1:] runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argTargetEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.AliasesTargets(tx).Restore(argAliasEmail, item) }, ItemString: func(item utils.EmailAddress) string { return argAliasEmail.String() + " -> " + item.String() }, FailureMessage: "failed to restore alias target", SuccessMessage: "Successfully restore alias target", } runner.Run() return nil }, }
View Source
var RestoreAliasesCmd = &cobra.Command{ Use: "aliases <email> [<email>...]", Aliases: []string{"alias"}, Short: "Restores soft-deleted aliases", Long: "Restores soft-deleted aliases.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Aliases(tx).Restore(item) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to restore alias", SuccessMessage: "Successfully restored alias", } runner.Run() return nil }, }
View Source
var RestoreCmd = &cobra.Command{
Use: "restore",
Short: "Restore soft-deleted mail system objects",
}
View Source
var RestoreDomainCatchallTargetsCmd = &cobra.Command{ Use: "catchall-targets <domain> <target-email> [<target-email>...]", Aliases: []string{"catchall-target", "catchalls", "catchall"}, Short: "Restores soft-deleted domain catch-all targets", Long: "Restores soft-deleted domain catch-all targets.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argDomain := args[0] argEmails := ParseEmailArgs(args[1:]) if len(argEmails) != len(args)-1 { return fmt.Errorf("invalid email arguments") } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.DomainsCatchallTargets(tx).Restore(argDomain, item) }, ItemString: func(item utils.EmailAddress) string { return "@" + argDomain + " -> " + item.String() }, FailureMessage: "failed to restore catchall target", SuccessMessage: "Successfully restored catchall target", } runner.Run() return nil }, }
View Source
var RestoreDomainsCmd = &cobra.Command{ Use: "domains <fqdn> [<fqdn>...]", Aliases: []string{"domain"}, Short: "Restores soft-deleted domains", Long: "Restores soft-deleted domains.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argDomains := ParseDomainFQDNArgs(args) if len(argDomains) != len(args) { return fmt.Errorf("invalid domain arguments") } runner := db.TxForEachRunner[string]{ Items: argDomains, Exec: func(tx *sql.Tx, item string) error { return db.Domains(tx).Restore(item) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to restore domain", SuccessMessage: "Successfully restored domain", } runner.Run() return nil }, }
View Source
var RestoreMailboxesCmd = &cobra.Command{ Use: "mailboxes <email> [<email>...]", Aliases: []string{"mailbox"}, Short: "Restores soft-deleted mailboxes", Long: "Restores soft-deleted mailboxes.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.Mailboxes(tx).Restore(item) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to restore mailbox", SuccessMessage: "Successfully restored mailbox", } runner.Run() return nil }, }
View Source
var RestoreRecipientsRelayedCmd = &cobra.Command{ Use: "recipients-relayed <email> [<email>...]", Aliases: []string{"recipient-relayed", "relayed-recipients", "relayed-recipient", "relayed"}, Short: "Restores soft-deleted relayed recipients", Long: "Restores soft-deleted relayed recipients.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { argEmails := ParseEmailArgs(args) if len(argEmails) != len(args) { return fmt.Errorf("invalid email arguments") } runner := db.TxForEachRunner[utils.EmailAddress]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddress) error { return db.RecipientsRelayed(tx).Restore(item) }, ItemString: func(item utils.EmailAddress) string { return item.String() }, FailureMessage: "failed to restore relayed recipient", SuccessMessage: "Successfully restored relayed recipient", } runner.Run() return nil }, }
View Source
var RestoreRemoteSendGrantsCmd = &cobra.Command{ Use: "send-grant <remote-name> <email> [<email>...]", Short: "Restores soft-deleted send grants for a remote", Long: "Restores soft-deleted send grants for a remote.", Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { argRemoteName := args[0] argEmails := ParseEmailOrWildcardArgs(args[1:]) if len(argEmails) != len(args[1:]) { return fmt.Errorf("invalid email or domain argument") } runner := db.TxForEachRunner[utils.EmailAddressOrWildcard]{ Items: argEmails, Exec: func(tx *sql.Tx, item utils.EmailAddressOrWildcard) error { return db.RemotesSendGrants(tx).Restore(argRemoteName, item) }, ItemString: func(item utils.EmailAddressOrWildcard) string { return argRemoteName + " -> " + item.String() }, FailureMessage: "failed to restore send grant", SuccessMessage: "Successfully restored send grant", } runner.Run() return nil }, }
View Source
var RestoreRemotesCmd = &cobra.Command{ Use: "remotes <name> [<name>...]", Aliases: []string{"remote"}, Short: "Restores soft-deleted remotes", Long: "Restores soft-deleted remotes.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Remotes(tx).Restore(item) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to restore remote", SuccessMessage: "Successfully restored remote", } runner.Run() return nil }, }
View Source
var RestoreTransportsCmd = &cobra.Command{ Use: "transports <name> [<name>...]", Aliases: []string{"transport"}, Short: "Restores soft-deleted transports", Long: "Restores soft-deleted transports.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { runner := db.TxForEachRunner[string]{ Items: args, Exec: func(tx *sql.Tx, item string) error { return db.Transports(tx).Restore(item) }, ItemString: func(item string) string { return item }, FailureMessage: "failed to restore transport", SuccessMessage: "Successfully restored transport", } runner.Run() return nil }, }
View Source
var SchemaCmd = &cobra.Command{
Use: "schema",
Short: "Manage database schema",
Long: `Manage database schema setup and upgrades`,
}
View Source
var SchemaDropUserCmd = &cobra.Command{ Use: "drop-user [username]", Short: "Drop an application-specific database user", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagNameFile, _ := cmd.Flags().GetString("name-file") flagEnvPrefix, _ := cmd.Flags().GetString("env-prefix") argUsername := "" if len(args) > 0 { argUsername = args[0] } userName, err := ResolveDynamicSourceArg(argUsername, flagNameFile, fmt.Sprintf("%s_NAME", flagEnvPrefix)) if err != nil { utils.PrintError(fmt.Errorf("failed to resolve username: %w", err)) return nil } dbConn, err := db.Connect() if err != nil { utils.PrintErrorWithMessage("Failed to connect to database", err) return nil } defer dbConn.Close() dbConfig := db.GetConfig() err = schema.DropUser(dbConn, dbConfig.DBName, dbConfig.User, userName) if err != nil { utils.PrintErrorWithMessage("Failed to drop database user", err) return nil } utils.PrintSuccess("Database user dropped successfully") return nil }, }
View Source
var SchemaEnsureUserCmd = &cobra.Command{ Use: "ensure-user [username]", Short: "Create/sync application-specific database user with limited permissions", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { flagType, _ := cmd.Flags().GetString("type") flagPasswordPrompt, _ := cmd.Flags().GetBool("password") flagPasswordStdin, _ := cmd.Flags().GetBool("password-stdin") flagTypeFile, _ := cmd.Flags().GetString("type-file") flagNameFile, _ := cmd.Flags().GetString("name-file") flagPasswordFile, _ := cmd.Flags().GetString("password-file") flagEnvPrefix, _ := cmd.Flags().GetString("env-prefix") argUsername := "" if len(args) > 0 { argUsername = args[0] } userType, err := ResolveDynamicSourceArg(flagType, flagTypeFile, fmt.Sprintf("%s_TYPE", flagEnvPrefix)) if err != nil { utils.PrintError(fmt.Errorf("failed to retreive user type: %w", err)) return nil } userName, err := ResolveDynamicSourceArg(argUsername, flagNameFile, fmt.Sprintf("%s_NAME", flagEnvPrefix)) if err != nil { utils.PrintError(fmt.Errorf("failed to retreive username: %w", err)) return nil } var password string if flagPasswordPrompt || flagPasswordStdin { password, err = ReadPassword(flagPasswordStdin) if err != nil { utils.PrintErrorWithMessage("failed to read password", err) return nil } } else { password, err = ResolveDynamicSourceArg("", flagPasswordFile, fmt.Sprintf("%s_PASSWORD", flagEnvPrefix)) if err != nil { utils.PrintError(fmt.Errorf("failed to retreive password: %w", err)) return nil } } dbConn, err := db.Connect() if err != nil { utils.PrintErrorWithMessage("Failed to connect to database", err) return nil } defer dbConn.Close() dbConfig := db.GetConfig() err = schema.EnsureUser(dbConn, dbConfig.DBName, userType, schema.User{ Name: userName, Password: password, }) if err != nil { utils.PrintErrorWithMessage("Failed to sync database user", err) return nil } utils.PrintSuccess("Database user synced successfully") return nil }, }
View Source
var SchemaPurgeCmd = &cobra.Command{ Use: "purge", Short: "Purge all schema and data from the database", Long: "Purge the entire database by dropping all tables, sequences, functions, and types.", RunE: func(cmd *cobra.Command, args []string) error { confirm, err := cmd.Flags().GetBool("confirm") if err != nil { utils.PrintErrorWithMessage("Failed to read confirmation flag", err) return nil } if !confirm { fmt.Printf("This will %s:\n", utils.RedStyle.Render("PERMANENTLY DELETE")) fmt.Println(" • All tables and their data") fmt.Println(" • All sequences") fmt.Println(" • All functions") fmt.Println(" • All custom types") fmt.Println("To proceed, use '--confirm'") os.Exit(1) } dbConn, err := db.Connect() if err != nil { utils.PrintErrorWithMessage("Failed to connect to database", err) return nil } defer dbConn.Close() fmt.Println("Purging database...") err = schema.Purge(dbConn) if err != nil { utils.PrintErrorWithMessage("Failed to purge database", err) return nil } utils.PrintSuccess("Schema purge completed successfully") return nil }, }
View Source
var SchemaStatusCmd = &cobra.Command{ Use: "status", Short: "Show current schema version", RunE: func(cmd *cobra.Command, args []string) error { dbConn, err := db.Connect() if err != nil { utils.PrintErrorWithMessage("failed to connect to database", err) return nil } defer dbConn.Close() currentVersion, err := schema.GetCurrentVersion(dbConn) if err != nil { utils.PrintErrorWithMessage("Failed to get current schema version", err) return nil } latestVersion, err := schema.GetLatestAvailableVersion() if err != nil { utils.PrintErrorWithMessage("Failed to get latest available schema version", err) return nil } if currentVersion > 0 && currentVersion < latestVersion { fmt.Println(utils.YellowStyle.Bold(true).Render("Schema upgrade available")) fmt.Printf("Installed schema: v%d\n", currentVersion) fmt.Printf("Available schema: v%d\n", latestVersion) } else if currentVersion > 0 && currentVersion == latestVersion { utils.PrintSuccess("Schema is up to date") fmt.Printf("Installed schema: v%d\n", currentVersion) } else { fmt.Println(utils.YellowStyle.Bold(true).Render("Schema is not installed")) fmt.Printf("Available schema: v%d\n", latestVersion) } return nil }, }
View Source
var SchemaUpgradeCmd = &cobra.Command{ Use: "upgrade", Short: "Upgrade database schema to latest version", Long: `Upgrade the database schema to the latest available version by applying pending migrations.`, RunE: func(cmd *cobra.Command, args []string) error { latestVersion, err := schema.GetLatestAvailableVersion() if err != nil { utils.PrintErrorWithMessage("Failed to get latest available schema version", err) return nil } dbConn, err := db.Connect() if err != nil { utils.PrintErrorWithMessage("Failed to connect to database", err) return nil } defer dbConn.Close() currentVersion, err := schema.GetCurrentVersion(dbConn) if err != nil { utils.PrintErrorWithMessage("Failed to get current schema version", err) return nil } if currentVersion >= latestVersion { utils.PrintSuccess("Schema is already up to date") return nil } if currentVersion == 0 { fmt.Printf("Installing schema v%d...\n", latestVersion) } else { fmt.Printf("Upgrading schema: v%d -> v%d...\n", currentVersion, latestVersion) } err = schema.Upgrade(dbConn, latestVersion) if err != nil { utils.PrintErrorWithMessage("Failed to upgrade schema", err) return nil } utils.PrintSuccess("Schema upgrade completed successfully") return nil }, }
Functions ¶
func DescribeCanonicalAddress ¶
func DescribeCanonicalAddress(r sq.BaseRunner, email utils.EmailAddress) (bool, error)
func ParseDomainFQDNArgs ¶
func ParseEmailArgs ¶
func ParseEmailArgs(args []string) []utils.EmailAddress
func ParseEmailOrWildcardArgs ¶
func ParseEmailOrWildcardArgs(args []string) []utils.EmailAddressOrWildcard
func PasswordHash ¶ added in v0.1.3
func ReadFileValue ¶
func ReadPassword ¶
func ReadPasswordHashed ¶
func RenderMetaSection ¶
RenderMetaSection returns a standardized table showing created/updated/deleted timestamps.
func ResolveDynamicSourceArg ¶
Types ¶
This section is empty.
Source Files
¶
- create.go
- create_aliases.go
- create_aliastargets.go
- create_domaincatchalltargets.go
- create_domains.go
- create_mailboxes.go
- create_recipientsrelayed.go
- create_remotes.go
- create_remotesendgrants.go
- create_transports.go
- delete.go
- delete_aliases.go
- delete_aliastargets.go
- delete_domaincatchalltargets.go
- delete_domains.go
- delete_mailboxes.go
- delete_recipientsrelayed.go
- delete_remotes.go
- delete_remotesendgrants.go
- delete_transports.go
- describe.go
- describe_aliases.go
- describe_domaincatchalltargets.go
- describe_domains.go
- describe_mailboxes.go
- describe_recipientsrelayed.go
- describe_remotes.go
- describe_transports.go
- disable.go
- disable_aliases.go
- disable_aliastargets.go
- disable_domaincatchalltargets.go
- disable_domains.go
- disable_mailboxes.go
- disable_recipientsrelayed.go
- disable_remotes.go
- enable.go
- enable_aliases.go
- enable_aliastargets.go
- enable_domains.go
- enable_domainscatchalltargets.go
- enable_mailboxes.go
- enable_recipientsrelayed.go
- enable_remotes.go
- helpers_args.go
- helpers_dynamic_source_arg.go
- helpers_files.go
- helpers_meta.go
- helpers_password.go
- list.go
- list_aliases.go
- list_aliastargets.go
- list_domains.go
- list_domainscatchalltargets.go
- list_mailboxes.go
- list_recipientsrelayed.go
- list_remotes.go
- list_remotesendgrants.go
- list_transports.go
- patch.go
- patch_aliases.go
- patch_aliastargets.go
- patch_domains.go
- patch_domainscatchalltargets.go
- patch_mailboxes.go
- patch_recipientsrelayed.go
- patch_remotes.go
- patch_transports.go
- rename.go
- rename_aliases.go
- rename_domains.go
- rename_mailboxes.go
- rename_recipientsrelayed.go
- rename_remotes.go
- rename_transports.go
- restore.go
- restore_aliases.go
- restore_aliastargets.go
- restore_domains.go
- restore_domainscatchalltargets.go
- restore_mailboxes.go
- restore_recipientsrelayed.go
- restore_remotes.go
- restore_remotesendgrants.go
- restore_transports.go
- root.go
- schema.go
- schema_drop_user.go
- schema_ensure_user.go
- schema_purge.go
- schema_status.go
- schema_upgrade.go
Click to show internal directories.
Click to hide internal directories.