Fix compile error in factory script (#2092)
## Description Go does not allow importing code from a file marked as package main into another file. ## Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [ ] 🕐 Yes, but in a later PR - [x] ⛔ No ## Type of change - [ ] 🌻 Feature - [x] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Test - [ ] 💻 CI/Deployment - [x] 🧹 Tech Debt/Cleanup ## Issue(s) * closes #2026 ## Test Plan - [x] 💪 Manual - [ ] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
580934b069
commit
6967f1bf6e
@ -3,25 +3,12 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
. "github.com/alcionai/corso/src/cli/print"
|
||||
"github.com/alcionai/corso/src/internal/common"
|
||||
"github.com/alcionai/corso/src/internal/connector"
|
||||
"github.com/alcionai/corso/src/internal/connector/mockconnector"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"github.com/alcionai/corso/src/pkg/account"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
"github.com/alcionai/corso/src/pkg/credentials"
|
||||
"github.com/alcionai/corso/src/cmd/factory/impl"
|
||||
"github.com/alcionai/corso/src/pkg/logger"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
"github.com/alcionai/corso/src/pkg/selectors"
|
||||
)
|
||||
|
||||
var factoryCmd = &cobra.Command{
|
||||
@ -42,17 +29,6 @@ var oneDriveCmd = &cobra.Command{
|
||||
RunE: handleOneDriveFactory,
|
||||
}
|
||||
|
||||
var (
|
||||
count int
|
||||
destination string
|
||||
tenant string
|
||||
user string
|
||||
)
|
||||
|
||||
// TODO: ErrGenerating = errors.New("not all items were successfully generated")
|
||||
|
||||
var ErrNotYetImplemeted = errors.New("not yet implemented")
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// CLI command handlers
|
||||
// ------------------------------------------------------------------------------------------
|
||||
@ -65,18 +41,18 @@ func main() {
|
||||
|
||||
// persistent flags that are common to all use cases
|
||||
fs := factoryCmd.PersistentFlags()
|
||||
fs.StringVar(&tenant, "tenant", "", "m365 tenant containing the user")
|
||||
fs.StringVar(&user, "user", "", "m365 user owning the new data")
|
||||
fs.StringVar(&impl.Tenant, "tenant", "", "m365 tenant containing the user")
|
||||
fs.StringVar(&impl.User, "user", "", "m365 user owning the new data")
|
||||
cobra.CheckErr(factoryCmd.MarkPersistentFlagRequired("user"))
|
||||
fs.IntVar(&count, "count", 0, "count of items to produce")
|
||||
fs.IntVar(&impl.Count, "count", 0, "count of items to produce")
|
||||
cobra.CheckErr(factoryCmd.MarkPersistentFlagRequired("count"))
|
||||
fs.StringVar(&destination, "destination", "", "destination of the new data (will create as needed)")
|
||||
fs.StringVar(&impl.Destination, "destination", "", "destination of the new data (will create as needed)")
|
||||
cobra.CheckErr(factoryCmd.MarkPersistentFlagRequired("destination"))
|
||||
|
||||
factoryCmd.AddCommand(exchangeCmd)
|
||||
addExchangeCommands(exchangeCmd)
|
||||
impl.AddExchangeCommands(exchangeCmd)
|
||||
factoryCmd.AddCommand(oneDriveCmd)
|
||||
addOneDriveCommands(oneDriveCmd)
|
||||
impl.AddOneDriveCommands(oneDriveCmd)
|
||||
|
||||
if err := factoryCmd.ExecuteContext(ctx); err != nil {
|
||||
logger.Flush(ctx)
|
||||
@ -85,180 +61,16 @@ func main() {
|
||||
}
|
||||
|
||||
func handleFactoryRoot(cmd *cobra.Command, args []string) error {
|
||||
Err(cmd.Context(), ErrNotYetImplemeted)
|
||||
Err(cmd.Context(), impl.ErrNotYetImplemeted)
|
||||
return cmd.Help()
|
||||
}
|
||||
|
||||
func handleExchangeFactory(cmd *cobra.Command, args []string) error {
|
||||
Err(cmd.Context(), ErrNotYetImplemeted)
|
||||
Err(cmd.Context(), impl.ErrNotYetImplemeted)
|
||||
return cmd.Help()
|
||||
}
|
||||
|
||||
func handleOneDriveFactory(cmd *cobra.Command, args []string) error {
|
||||
Err(cmd.Context(), ErrNotYetImplemeted)
|
||||
Err(cmd.Context(), impl.ErrNotYetImplemeted)
|
||||
return cmd.Help()
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Restoration
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
type dataBuilderFunc func(id, now, subject, body string) []byte
|
||||
|
||||
func generateAndRestoreItems(
|
||||
ctx context.Context,
|
||||
gc *connector.GraphConnector,
|
||||
acct account.Account,
|
||||
service path.ServiceType,
|
||||
cat path.CategoryType,
|
||||
sel selectors.Selector,
|
||||
userID, destFldr string,
|
||||
howMany int,
|
||||
dbf dataBuilderFunc,
|
||||
) (*details.Details, error) {
|
||||
items := make([]item, 0, howMany)
|
||||
|
||||
for i := 0; i < howMany; i++ {
|
||||
var (
|
||||
now = common.Now()
|
||||
nowLegacy = common.FormatLegacyTime(time.Now())
|
||||
id = uuid.NewString()
|
||||
subject = "automated " + now[:16] + " - " + id[:8]
|
||||
body = "automated " + cat.String() + " generation for " + userID + " at " + now + " - " + id
|
||||
)
|
||||
|
||||
items = append(items, item{
|
||||
name: id,
|
||||
data: dbf(id, nowLegacy, subject, body),
|
||||
})
|
||||
}
|
||||
|
||||
collections := []collection{{
|
||||
pathElements: []string{destFldr},
|
||||
category: cat,
|
||||
items: items,
|
||||
}}
|
||||
|
||||
// TODO: fit the desination to the containers
|
||||
dest := control.DefaultRestoreDestination(common.SimpleTimeTesting)
|
||||
dest.ContainerName = destFldr
|
||||
|
||||
dataColls, err := buildCollections(
|
||||
service,
|
||||
acct.ID(), userID,
|
||||
dest,
|
||||
collections,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Infof(ctx, "Generating %d %s items in %s\n", howMany, cat, destination)
|
||||
|
||||
return gc.RestoreDataCollections(ctx, acct, sel, dest, dataColls)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Common Helpers
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
func getGCAndVerifyUser(ctx context.Context, userID string) (*connector.GraphConnector, account.Account, error) {
|
||||
tid := common.First(tenant, os.Getenv(account.AzureTenantID))
|
||||
|
||||
// get account info
|
||||
m365Cfg := account.M365Config{
|
||||
M365: credentials.GetM365(),
|
||||
AzureTenantID: tid,
|
||||
}
|
||||
|
||||
acct, err := account.NewAccount(account.ProviderM365, m365Cfg)
|
||||
if err != nil {
|
||||
return nil, account.Account{}, errors.Wrap(err, "finding m365 account details")
|
||||
}
|
||||
|
||||
// build a graph connector
|
||||
gc, err := connector.NewGraphConnector(ctx, acct, connector.Users)
|
||||
if err != nil {
|
||||
return nil, account.Account{}, errors.Wrap(err, "connecting to graph api")
|
||||
}
|
||||
|
||||
normUsers := map[string]struct{}{}
|
||||
|
||||
for k := range gc.Users {
|
||||
normUsers[strings.ToLower(k)] = struct{}{}
|
||||
}
|
||||
|
||||
if _, ok := normUsers[strings.ToLower(user)]; !ok {
|
||||
return nil, account.Account{}, errors.New("user not found within tenant")
|
||||
}
|
||||
|
||||
return gc, acct, nil
|
||||
}
|
||||
|
||||
type item struct {
|
||||
name string
|
||||
data []byte
|
||||
}
|
||||
|
||||
type collection struct {
|
||||
// Elements (in order) for the path representing this collection. Should
|
||||
// only contain elements after the prefix that corso uses for the path. For
|
||||
// example, a collection for the Inbox folder in exchange mail would just be
|
||||
// "Inbox".
|
||||
pathElements []string
|
||||
category path.CategoryType
|
||||
items []item
|
||||
}
|
||||
|
||||
func buildCollections(
|
||||
service path.ServiceType,
|
||||
tenant, user string,
|
||||
dest control.RestoreDestination,
|
||||
colls []collection,
|
||||
) ([]data.Collection, error) {
|
||||
collections := make([]data.Collection, 0, len(colls))
|
||||
|
||||
for _, c := range colls {
|
||||
pth, err := toDataLayerPath(
|
||||
service,
|
||||
tenant,
|
||||
user,
|
||||
c.category,
|
||||
c.pathElements,
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mc := mockconnector.NewMockExchangeCollection(pth, len(c.items))
|
||||
|
||||
for i := 0; i < len(c.items); i++ {
|
||||
mc.Names[i] = c.items[i].name
|
||||
mc.Data[i] = c.items[i].data
|
||||
}
|
||||
|
||||
collections = append(collections, mc)
|
||||
}
|
||||
|
||||
return collections, nil
|
||||
}
|
||||
|
||||
func toDataLayerPath(
|
||||
service path.ServiceType,
|
||||
tenant, user string,
|
||||
category path.CategoryType,
|
||||
elements []string,
|
||||
isItem bool,
|
||||
) (path.Path, error) {
|
||||
pb := path.Builder{}.Append(elements...)
|
||||
|
||||
switch service {
|
||||
case path.ExchangeService:
|
||||
return pb.ToDataLayerExchangePathForCategory(tenant, user, category, isItem)
|
||||
case path.OneDriveService:
|
||||
return pb.ToDataLayerOneDrivePath(tenant, user, isItem)
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("unknown service %s", service.String())
|
||||
}
|
||||
|
||||
198
src/cmd/factory/impl/common.go
Normal file
198
src/cmd/factory/impl/common.go
Normal file
@ -0,0 +1,198 @@
|
||||
package impl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
. "github.com/alcionai/corso/src/cli/print"
|
||||
"github.com/alcionai/corso/src/internal/common"
|
||||
"github.com/alcionai/corso/src/internal/connector"
|
||||
"github.com/alcionai/corso/src/internal/connector/mockconnector"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"github.com/alcionai/corso/src/pkg/account"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
"github.com/alcionai/corso/src/pkg/credentials"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
"github.com/alcionai/corso/src/pkg/selectors"
|
||||
)
|
||||
|
||||
var (
|
||||
Count int
|
||||
Destination string
|
||||
Tenant string
|
||||
User string
|
||||
)
|
||||
|
||||
// TODO: ErrGenerating = errors.New("not all items were successfully generated")
|
||||
|
||||
var ErrNotYetImplemeted = errors.New("not yet implemented")
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Restoration
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
type dataBuilderFunc func(id, now, subject, body string) []byte
|
||||
|
||||
func generateAndRestoreItems(
|
||||
ctx context.Context,
|
||||
gc *connector.GraphConnector,
|
||||
acct account.Account,
|
||||
service path.ServiceType,
|
||||
cat path.CategoryType,
|
||||
sel selectors.Selector,
|
||||
tenantID, userID, destFldr string,
|
||||
howMany int,
|
||||
dbf dataBuilderFunc,
|
||||
) (*details.Details, error) {
|
||||
items := make([]item, 0, howMany)
|
||||
|
||||
for i := 0; i < howMany; i++ {
|
||||
var (
|
||||
now = common.Now()
|
||||
nowLegacy = common.FormatLegacyTime(time.Now())
|
||||
id = uuid.NewString()
|
||||
subject = "automated " + now[:16] + " - " + id[:8]
|
||||
body = "automated " + cat.String() + " generation for " + userID + " at " + now + " - " + id
|
||||
)
|
||||
|
||||
items = append(items, item{
|
||||
name: id,
|
||||
data: dbf(id, nowLegacy, subject, body),
|
||||
})
|
||||
}
|
||||
|
||||
collections := []collection{{
|
||||
pathElements: []string{destFldr},
|
||||
category: cat,
|
||||
items: items,
|
||||
}}
|
||||
|
||||
// TODO: fit the desination to the containers
|
||||
dest := control.DefaultRestoreDestination(common.SimpleTimeTesting)
|
||||
dest.ContainerName = destFldr
|
||||
|
||||
dataColls, err := buildCollections(
|
||||
service,
|
||||
tenantID, userID,
|
||||
dest,
|
||||
collections,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Infof(ctx, "Generating %d %s items in %s\n", howMany, cat, Destination)
|
||||
|
||||
return gc.RestoreDataCollections(ctx, acct, sel, dest, dataColls)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Common Helpers
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
func getGCAndVerifyUser(ctx context.Context, userID string) (*connector.GraphConnector, account.Account, error) {
|
||||
tid := common.First(Tenant, os.Getenv(account.AzureTenantID))
|
||||
|
||||
// get account info
|
||||
m365Cfg := account.M365Config{
|
||||
M365: credentials.GetM365(),
|
||||
AzureTenantID: tid,
|
||||
}
|
||||
|
||||
acct, err := account.NewAccount(account.ProviderM365, m365Cfg)
|
||||
if err != nil {
|
||||
return nil, account.Account{}, errors.Wrap(err, "finding m365 account details")
|
||||
}
|
||||
|
||||
// build a graph connector
|
||||
gc, err := connector.NewGraphConnector(ctx, acct, connector.Users)
|
||||
if err != nil {
|
||||
return nil, account.Account{}, errors.Wrap(err, "connecting to graph api")
|
||||
}
|
||||
|
||||
normUsers := map[string]struct{}{}
|
||||
|
||||
for k := range gc.Users {
|
||||
normUsers[strings.ToLower(k)] = struct{}{}
|
||||
}
|
||||
|
||||
if _, ok := normUsers[strings.ToLower(User)]; !ok {
|
||||
return nil, account.Account{}, errors.New("user not found within tenant")
|
||||
}
|
||||
|
||||
return gc, acct, nil
|
||||
}
|
||||
|
||||
type item struct {
|
||||
name string
|
||||
data []byte
|
||||
}
|
||||
|
||||
type collection struct {
|
||||
// Elements (in order) for the path representing this collection. Should
|
||||
// only contain elements after the prefix that corso uses for the path. For
|
||||
// example, a collection for the Inbox folder in exchange mail would just be
|
||||
// "Inbox".
|
||||
pathElements []string
|
||||
category path.CategoryType
|
||||
items []item
|
||||
}
|
||||
|
||||
func buildCollections(
|
||||
service path.ServiceType,
|
||||
tenant, user string,
|
||||
dest control.RestoreDestination,
|
||||
colls []collection,
|
||||
) ([]data.Collection, error) {
|
||||
collections := make([]data.Collection, 0, len(colls))
|
||||
|
||||
for _, c := range colls {
|
||||
pth, err := toDataLayerPath(
|
||||
service,
|
||||
tenant,
|
||||
user,
|
||||
c.category,
|
||||
c.pathElements,
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mc := mockconnector.NewMockExchangeCollection(pth, len(c.items))
|
||||
|
||||
for i := 0; i < len(c.items); i++ {
|
||||
mc.Names[i] = c.items[i].name
|
||||
mc.Data[i] = c.items[i].data
|
||||
}
|
||||
|
||||
collections = append(collections, mc)
|
||||
}
|
||||
|
||||
return collections, nil
|
||||
}
|
||||
|
||||
func toDataLayerPath(
|
||||
service path.ServiceType,
|
||||
tenant, user string,
|
||||
category path.CategoryType,
|
||||
elements []string,
|
||||
isItem bool,
|
||||
) (path.Path, error) {
|
||||
pb := path.Builder{}.Append(elements...)
|
||||
|
||||
switch service {
|
||||
case path.ExchangeService:
|
||||
return pb.ToDataLayerExchangePathForCategory(tenant, user, category, isItem)
|
||||
case path.OneDriveService:
|
||||
return pb.ToDataLayerOneDrivePath(tenant, user, isItem)
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("unknown service %s", service.String())
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package impl
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
@ -30,7 +30,7 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func addExchangeCommands(cmd *cobra.Command) {
|
||||
func AddExchangeCommands(cmd *cobra.Command) {
|
||||
cmd.AddCommand(emailsCmd)
|
||||
cmd.AddCommand(eventsCmd)
|
||||
cmd.AddCommand(contactsCmd)
|
||||
@ -47,7 +47,7 @@ func handleExchangeEmailFactory(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
gc, acct, err := getGCAndVerifyUser(ctx, user)
|
||||
gc, acct, err := getGCAndVerifyUser(ctx, User)
|
||||
if err != nil {
|
||||
return Only(ctx, err)
|
||||
}
|
||||
@ -58,12 +58,12 @@ func handleExchangeEmailFactory(cmd *cobra.Command, args []string) error {
|
||||
acct,
|
||||
service,
|
||||
category,
|
||||
selectors.NewExchangeRestore([]string{user}).Selector,
|
||||
user, destination,
|
||||
count,
|
||||
selectors.NewExchangeRestore([]string{User}).Selector,
|
||||
Tenant, User, Destination,
|
||||
Count,
|
||||
func(id, now, subject, body string) []byte {
|
||||
return mockconnector.GetMockMessageWith(
|
||||
user, user, user,
|
||||
User, User, User,
|
||||
subject, body, body,
|
||||
now, now, now, now)
|
||||
},
|
||||
@ -88,7 +88,7 @@ func handleExchangeCalendarEventFactory(cmd *cobra.Command, args []string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
gc, acct, err := getGCAndVerifyUser(ctx, user)
|
||||
gc, acct, err := getGCAndVerifyUser(ctx, User)
|
||||
if err != nil {
|
||||
return Only(ctx, err)
|
||||
}
|
||||
@ -99,12 +99,12 @@ func handleExchangeCalendarEventFactory(cmd *cobra.Command, args []string) error
|
||||
acct,
|
||||
service,
|
||||
category,
|
||||
selectors.NewExchangeRestore([]string{user}).Selector,
|
||||
user, destination,
|
||||
count,
|
||||
selectors.NewExchangeRestore([]string{User}).Selector,
|
||||
Tenant, User, Destination,
|
||||
Count,
|
||||
func(id, now, subject, body string) []byte {
|
||||
return mockconnector.GetMockEventWith(
|
||||
user, subject, body, body,
|
||||
User, subject, body, body,
|
||||
now, now, false)
|
||||
},
|
||||
)
|
||||
@ -128,7 +128,7 @@ func handleExchangeContactFactory(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
gc, acct, err := getGCAndVerifyUser(ctx, user)
|
||||
gc, acct, err := getGCAndVerifyUser(ctx, User)
|
||||
if err != nil {
|
||||
return Only(ctx, err)
|
||||
}
|
||||
@ -139,9 +139,9 @@ func handleExchangeContactFactory(cmd *cobra.Command, args []string) error {
|
||||
acct,
|
||||
service,
|
||||
category,
|
||||
selectors.NewExchangeRestore([]string{user}).Selector,
|
||||
user, destination,
|
||||
count,
|
||||
selectors.NewExchangeRestore([]string{User}).Selector,
|
||||
Tenant, User, Destination,
|
||||
Count,
|
||||
func(id, now, subject, body string) []byte {
|
||||
given, mid, sur := id[:8], id[9:13], id[len(id)-12:]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package impl
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
@ -13,7 +13,7 @@ var filesCmd = &cobra.Command{
|
||||
RunE: handleOneDriveFileFactory,
|
||||
}
|
||||
|
||||
func addOneDriveCommands(cmd *cobra.Command) {
|
||||
func AddOneDriveCommands(cmd *cobra.Command) {
|
||||
cmd.AddCommand(filesCmd)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user