remove the golang purge script (#3544)
fully replaced by powershell scripts
This commit is contained in:
parent
27d5889293
commit
8dc829eebe
@ -1,325 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
. "github.com/alcionai/corso/src/cli/print"
|
||||
"github.com/alcionai/corso/src/cli/utils"
|
||||
"github.com/alcionai/corso/src/internal/common/dttm"
|
||||
"github.com/alcionai/corso/src/internal/common/str"
|
||||
"github.com/alcionai/corso/src/internal/connector"
|
||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||
"github.com/alcionai/corso/src/internal/connector/onedrive"
|
||||
"github.com/alcionai/corso/src/pkg/account"
|
||||
"github.com/alcionai/corso/src/pkg/credentials"
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/logger"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||
)
|
||||
|
||||
var purgeCmd = &cobra.Command{
|
||||
Use: "purge",
|
||||
Short: "Purge all types of m365 folders",
|
||||
RunE: handleAllFolderPurge,
|
||||
}
|
||||
|
||||
var oneDriveCmd = &cobra.Command{
|
||||
Use: "onedrive",
|
||||
Short: "Purges OneDrive folders",
|
||||
RunE: handleOneDriveFolderPurge,
|
||||
}
|
||||
|
||||
var (
|
||||
before string
|
||||
user string
|
||||
tenant string
|
||||
prefix string
|
||||
)
|
||||
|
||||
var ErrPurging = clues.New("not all items were successfully purged")
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// CLI command handlers
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
func main() {
|
||||
ls := logger.Settings{
|
||||
Level: logger.LLDebug,
|
||||
Format: logger.LFText,
|
||||
}
|
||||
ctx, _ := logger.CtxOrSeed(context.Background(), ls)
|
||||
ctx = SetRootCmd(ctx, purgeCmd)
|
||||
|
||||
defer logger.Flush(ctx)
|
||||
|
||||
fs := purgeCmd.PersistentFlags()
|
||||
fs.StringVar(&before, "before", "", "folders older than this date are deleted. (default: now in UTC)")
|
||||
fs.StringVar(&user, "user", "", "m365 user id whose folders will be deleted")
|
||||
cobra.CheckErr(purgeCmd.MarkPersistentFlagRequired("user"))
|
||||
fs.StringVar(&tenant, "tenant", "", "m365 tenant containing the user")
|
||||
fs.StringVar(&prefix, "prefix", "", "filters mail folders by displayName prefix")
|
||||
cobra.CheckErr(purgeCmd.MarkPersistentFlagRequired("prefix"))
|
||||
|
||||
purgeCmd.AddCommand(oneDriveCmd)
|
||||
|
||||
if err := purgeCmd.ExecuteContext(ctx); err != nil {
|
||||
logger.Flush(ctx)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func handleAllFolderPurge(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
|
||||
if utils.HasNoFlagsAndShownHelp(cmd) {
|
||||
return nil
|
||||
}
|
||||
|
||||
acct, gc, t, err := getGCAndBoundaryTime(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = runPurgeForEachUser(
|
||||
ctx,
|
||||
acct,
|
||||
gc,
|
||||
t,
|
||||
purgeOneDriveFolders,
|
||||
)
|
||||
if err != nil {
|
||||
return Only(ctx, ErrPurging)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleOneDriveFolderPurge(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
|
||||
if utils.HasNoFlagsAndShownHelp(cmd) {
|
||||
return nil
|
||||
}
|
||||
|
||||
acct, gc, t, err := getGCAndBoundaryTime(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := runPurgeForEachUser(ctx, acct, gc, t, purgeOneDriveFolders); err != nil {
|
||||
logger.Ctx(ctx).Error(err)
|
||||
return Only(ctx, clues.Wrap(ErrPurging, "OneDrive folders"))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Purge Controllers
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
type purgable interface {
|
||||
GetDisplayName() *string
|
||||
GetId() *string
|
||||
}
|
||||
|
||||
type purger func(context.Context, *connector.GraphConnector, time.Time, string) error
|
||||
|
||||
func runPurgeForEachUser(
|
||||
ctx context.Context,
|
||||
acct account.Account,
|
||||
gc *connector.GraphConnector,
|
||||
boundary time.Time,
|
||||
ps ...purger,
|
||||
) error {
|
||||
users, err := m365.Users(ctx, acct, fault.New(true))
|
||||
if err != nil {
|
||||
return clues.Wrap(err, "getting users")
|
||||
}
|
||||
|
||||
for _, u := range userOrUsers(user, users) {
|
||||
Infof(ctx, "\nUser: %s - %s", u.PrincipalName, u.ID)
|
||||
|
||||
for _, p := range ps {
|
||||
if err := p(ctx, gc, boundary, u.PrincipalName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ----- OneDrive
|
||||
|
||||
func purgeOneDriveFolders(
|
||||
ctx context.Context,
|
||||
gc *connector.GraphConnector,
|
||||
boundary time.Time,
|
||||
uid string,
|
||||
) error {
|
||||
getter := func(gs graph.Servicer, uid, prefix string) ([]purgable, error) {
|
||||
pager, err := onedrive.PagerForSource(onedrive.OneDriveSource, gs, uid, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfs, err := onedrive.GetAllFolders(ctx, gs, pager, prefix, fault.New(true))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
purgables := make([]purgable, len(cfs))
|
||||
|
||||
for i, v := range cfs {
|
||||
purgables[i] = v
|
||||
}
|
||||
|
||||
return purgables, nil
|
||||
}
|
||||
|
||||
deleter := func(gs graph.Servicer, uid string, f purgable) error {
|
||||
driveFolder, ok := f.(*onedrive.Displayable)
|
||||
if !ok {
|
||||
return clues.New("non-OneDrive item")
|
||||
}
|
||||
|
||||
return api.DeleteDriveItem(
|
||||
ctx,
|
||||
gs,
|
||||
*driveFolder.GetParentReference().GetDriveId(),
|
||||
*f.GetId())
|
||||
}
|
||||
|
||||
return purgeFolders(ctx, gc, boundary, "OneDrive Folders", uid, getter, deleter)
|
||||
}
|
||||
|
||||
// ----- controller
|
||||
|
||||
func purgeFolders(
|
||||
ctx context.Context,
|
||||
gc *connector.GraphConnector,
|
||||
boundary time.Time,
|
||||
data, uid string,
|
||||
getter func(graph.Servicer, string, string) ([]purgable, error),
|
||||
deleter func(graph.Servicer, string, purgable) error,
|
||||
) error {
|
||||
Infof(ctx, "Container: %s", data)
|
||||
|
||||
// get them folders
|
||||
fs, err := getter(gc.Service, uid, prefix)
|
||||
if err != nil {
|
||||
return Only(ctx, clues.Wrap(err, "retrieving folders: "+data))
|
||||
}
|
||||
|
||||
if len(fs) == 0 {
|
||||
Info(ctx, "None Matched")
|
||||
return nil
|
||||
}
|
||||
|
||||
var errs error
|
||||
|
||||
// delete any containers that don't pass the boundary
|
||||
for _, fld := range fs {
|
||||
// compare the folder time to the deletion boundary time first
|
||||
displayName := *fld.GetDisplayName()
|
||||
|
||||
dnTime, err := dttm.ExtractTime(displayName)
|
||||
if err != nil && !errors.Is(err, dttm.ErrNoTimeString) {
|
||||
err = clues.Wrap(err, "!! Error: parsing container: "+displayName)
|
||||
Info(ctx, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if !dnTime.Before(boundary) || dnTime == (time.Time{}) {
|
||||
continue
|
||||
}
|
||||
|
||||
Infof(ctx, "∙ Deleting [%s]", displayName)
|
||||
|
||||
err = deleter(gc.Service, uid, fld)
|
||||
if err != nil {
|
||||
err = clues.Wrap(err, "!! Error")
|
||||
Info(ctx, err)
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
func getGC(ctx context.Context) (account.Account, *connector.GraphConnector, error) {
|
||||
// get account info
|
||||
m365Cfg := account.M365Config{
|
||||
M365: credentials.GetM365(),
|
||||
AzureTenantID: str.First(tenant, os.Getenv(account.AzureTenantID)),
|
||||
}
|
||||
|
||||
acct, err := account.NewAccount(account.ProviderM365, m365Cfg)
|
||||
if err != nil {
|
||||
return account.Account{}, nil, Only(ctx, clues.Wrap(err, "finding m365 account details"))
|
||||
}
|
||||
|
||||
gc, err := connector.NewGraphConnector(ctx, acct, connector.Users)
|
||||
if err != nil {
|
||||
return account.Account{}, nil, Only(ctx, clues.Wrap(err, "connecting to graph api"))
|
||||
}
|
||||
|
||||
return acct, gc, nil
|
||||
}
|
||||
|
||||
func getBoundaryTime(ctx context.Context) (time.Time, error) {
|
||||
// format the time input
|
||||
var (
|
||||
err error
|
||||
boundaryTime = time.Now().UTC()
|
||||
)
|
||||
|
||||
if len(before) > 0 {
|
||||
boundaryTime, err = dttm.ParseTime(before)
|
||||
if err != nil {
|
||||
return time.Time{}, Only(ctx, clues.Wrap(err, "parsing before flag to time"))
|
||||
}
|
||||
}
|
||||
|
||||
return boundaryTime, nil
|
||||
}
|
||||
|
||||
func getGCAndBoundaryTime(
|
||||
ctx context.Context,
|
||||
) (account.Account, *connector.GraphConnector, time.Time, error) {
|
||||
acct, gc, err := getGC(ctx)
|
||||
if err != nil {
|
||||
return account.Account{}, nil, time.Time{}, err
|
||||
}
|
||||
|
||||
t, err := getBoundaryTime(ctx)
|
||||
if err != nil {
|
||||
return account.Account{}, nil, time.Time{}, err
|
||||
}
|
||||
|
||||
return acct, gc, t, nil
|
||||
}
|
||||
|
||||
func userOrUsers(u string, us []*m365.User) []*m365.User {
|
||||
if len(u) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if u == "*" {
|
||||
return us
|
||||
}
|
||||
|
||||
return []*m365.User{{PrincipalName: u}}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user