Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
document and release groups and teams (#4238)
Browse files Browse the repository at this point in the history
Adds the release documentation and reveals all cli commands for groups and teams channelMessages and files support.

---

#### Does this PR need a docs update or release note?

- [x] ✅ Yes, it's included

#### Type of change

- [x] 🗺️ Documentation

#### Issue(s)

* #3988 

#### Test Plan

- [x] 💪 Manual
  • Loading branch information
ryanfkeepers authored Sep 19, 2023
1 parent 9a04d71 commit a60d599
Show file tree
Hide file tree
Showing 18 changed files with 100 additions and 60 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased] (beta)

### Added
- Groups and Teams service support available as a feature preview! Channel messages and Files are now available for backup and restore in the CLI: `corso backup create groups --group '*'`
* The cli commands for "groups" and "teams" can be used interchangably, and will operate on the same backup data.
* New permissions are required to backup Channel messages. See the [Corso Documentation](https://corsobackup.io/docs/setup/m365-access/#configure-required-permissions) for complete details.
Even though Channel message restoration is not available, message write permissions are included to cover future integration.
* This is a feature preview, and may be subject to breaking changes based on feedback and testing.

### Changed
- Switched to Go 1.21
- SharePoint exported libraries are now exported with a `Libraries` prefix.
Expand Down
10 changes: 1 addition & 9 deletions src/cli/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package backup
import (
"context"
"fmt"
"os"
"strings"

"github.com/alcionai/clues"
Expand Down Expand Up @@ -39,9 +38,7 @@ var serviceCommands = []func(cmd *cobra.Command) *cobra.Command{
addExchangeCommands,
addOneDriveCommands,
addSharePointCommands,
// awaiting release
// addGroupsCommands,
// addTeamsCommands,
addGroupsCommands,
}

// AddCommands attaches all `corso backup * *` commands to the parent.
Expand All @@ -56,11 +53,6 @@ func AddCommands(cmd *cobra.Command) {
for _, addBackupTo := range serviceCommands {
addBackupTo(subCommand)
}

// delete after release
if len(os.Getenv("CORSO_ENABLE_GROUPS")) > 0 {
addGroupsCommands(subCommand)
}
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/cli/backup/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
const (
groupsServiceCommand = "groups"
teamsServiceCommand = "teams"
groupsServiceCommandCreateUseSuffix = "--group <groupsName> | '" + flags.Wildcard + "'"
groupsServiceCommandCreateUseSuffix = "--group <groupName> | '" + flags.Wildcard + "'"
groupsServiceCommandDeleteUseSuffix = "--backup <backupId>"
groupsServiceCommandDetailsUseSuffix = "--backup <backupId>"
)
Expand Down Expand Up @@ -66,7 +66,7 @@ func addGroupsCommands(cmd *cobra.Command) *cobra.Command {

switch cmd.Use {
case createCommand:
c, fs = utils.AddCommand(cmd, groupsCreateCmd(), utils.MarkPreReleaseCommand())
c, fs = utils.AddCommand(cmd, groupsCreateCmd(), utils.MarkPreviewCommand())
fs.SortFlags = false

c.Use = c.Use + " " + groupsServiceCommandCreateUseSuffix
Expand All @@ -84,7 +84,7 @@ func addGroupsCommands(cmd *cobra.Command) *cobra.Command {
flags.AddForceItemDataDownloadFlag(c)

case listCommand:
c, fs = utils.AddCommand(cmd, groupsListCmd(), utils.MarkPreReleaseCommand())
c, fs = utils.AddCommand(cmd, groupsListCmd(), utils.MarkPreviewCommand())
fs.SortFlags = false

flags.AddBackupIDFlag(c, false)
Expand All @@ -96,7 +96,7 @@ func addGroupsCommands(cmd *cobra.Command) *cobra.Command {
addRecoveredErrorsFN(c)

case detailsCommand:
c, fs = utils.AddCommand(cmd, groupsDetailsCmd(), utils.MarkPreReleaseCommand())
c, fs = utils.AddCommand(cmd, groupsDetailsCmd(), utils.MarkPreviewCommand())
fs.SortFlags = false

c.Use = c.Use + " " + groupsServiceCommandDetailsUseSuffix
Expand All @@ -114,7 +114,7 @@ func addGroupsCommands(cmd *cobra.Command) *cobra.Command {
flags.AddSharePointDetailsAndRestoreFlags(c)

case deleteCommand:
c, fs = utils.AddCommand(cmd, groupsDeleteCmd(), utils.MarkPreReleaseCommand())
c, fs = utils.AddCommand(cmd, groupsDeleteCmd(), utils.MarkPreviewCommand())
fs.SortFlags = false

c.Use = c.Use + " " + groupsServiceCommandDeleteUseSuffix
Expand Down
10 changes: 1 addition & 9 deletions src/cli/export/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package export
import (
"context"
"errors"
"os"

"github.com/alcionai/clues"
"github.com/spf13/cobra"
Expand All @@ -21,9 +20,7 @@ import (
var exportCommands = []func(cmd *cobra.Command) *cobra.Command{
addOneDriveCommands,
addSharePointCommands,
// awaiting release
// addGroupsCommands,
// addTeamsCommands,
addGroupsCommands,
}

// AddCommands attaches all `corso export * *` commands to the parent.
Expand All @@ -34,11 +31,6 @@ func AddCommands(cmd *cobra.Command) {
for _, addExportTo := range exportCommands {
addExportTo(exportC)
}

// delete after release
if len(os.Getenv("CORSO_ENABLE_GROUPS")) > 0 {
addGroupsCommands(exportC)
}
}

const exportCommand = "export"
Expand Down
12 changes: 8 additions & 4 deletions src/cli/export/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func addGroupsCommands(cmd *cobra.Command) *cobra.Command {

switch cmd.Use {
case exportCommand:
c, fs = utils.AddCommand(cmd, groupsExportCmd(), utils.MarkPreReleaseCommand())
c, fs = utils.AddCommand(cmd, groupsExportCmd(), utils.MarkPreviewCommand())

c.Use = c.Use + " " + groupsServiceCommandUseSuffix

Expand All @@ -43,16 +43,20 @@ const (
groupsServiceCommandUseSuffix = "<destination> --backup <backupId>"

//nolint:lll
groupsServiceCommandExportExamples = `# Export a message in Marketing's last backup (1234abcd...) to my-exports directory
groupsServiceCommandExportExamples = `# Export a message in Marketing's last backup (1234abcd...) to /my-exports
corso export groups my-exports --backup 1234abcd-12ab-cd34-56de-1234abcd --message 98765abcdef
# Export all messages named in channel "Finance Reports" to the current directory
corso export groups . --backup 1234abcd-12ab-cd34-56de-1234abcd \
--message '*' --channel "Finance Reports"
# Export all messages in channel "Finance Reports" that were created before 2020 to my-exports
# Export all messages in channel "Finance Reports" that were created before 2020 to /my-exports
corso export groups my-exports --backup 1234abcd-12ab-cd34-56de-1234abcd
--channel "Finance Reports" --message-created-before 2020-01-01T00:00:00`
--channel "Finance Reports" --message-created-before 2020-01-01T00:00:00
# Export all files and folders in folder "Documents/Finance Reports" that were created before 2020 to /my-exports
corso export groups my-exports --backup 1234abcd-12ab-cd34-56de-1234abcd \
--folder "Documents/Finance Reports" --file-created-before 2020-01-01T00:00:00`
)

// `corso export groups [<flag>...] <destination>`
Expand Down
8 changes: 4 additions & 4 deletions src/cli/export/onedrive.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ const (
oneDriveServiceCommandUseSuffix = "<destination> --backup <backupId>"

//nolint:lll
oneDriveServiceCommandExportExamples = `# Export file with ID 98765abcdef in Bob's last backup (1234abcd...) to my-exports directory
oneDriveServiceCommandExportExamples = `# Export file with ID 98765abcdef in Bob's last backup (1234abcd...) to /my-exports
corso export onedrive my-exports --backup 1234abcd-12ab-cd34-56de-1234abcd --file 98765abcdef
# Export files named "FY2021 Planning.xlsx" in "Documents/Finance Reports" to current directory
# Export files named "FY2021 Planning.xlsx" in "Documents/Finance Reports" to he current directory
corso export onedrive . --backup 1234abcd-12ab-cd34-56de-1234abcd \
--file "FY2021 Planning.xlsx" --folder "Documents/Finance Reports"
# Export all files and folders in folder "Documents/Finance Reports" that were created before 2020 to my-exports
corso export onedrive my-exports --backup 1234abcd-12ab-cd34-56de-1234abcd
# Export all files and folders in folder "Documents/Finance Reports" that were created before 2020 to /my-exports
corso export onedrive my-exports --backup 1234abcd-12ab-cd34-56de-1234abcd \
--folder "Documents/Finance Reports" --file-created-before 2020-01-01T00:00:00`
)

Expand Down
12 changes: 6 additions & 6 deletions src/cli/export/sharepoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@ const (
sharePointServiceCommandUseSuffix = "<destination> --backup <backupId>"

//nolint:lll
sharePointServiceCommandExportExamples = `# Export file with ID 98765abcdef in Bob's latest backup (1234abcd...) to my-exports directory
sharePointServiceCommandExportExamples = `# Export file with ID 98765abcdef in Bob's latest backup (1234abcd...) to /my-exports
corso export sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --file 98765abcdef my-exports
# Export files named "ServerRenderTemplate.xsl" in the folder "Display Templates/Style Sheets". as archive to current directory
# Export file "ServerRenderTemplate.xsl" in "Display Templates/Style Sheets" as archive to the current directory
corso export sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
--file "ServerRenderTemplate.xsl" --folder "Display Templates/Style Sheets" --archive .
# Export all files in the folder "Display Templates/Style Sheets" that were created before 2020 to my-exports directory.
corso export sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd
# Export all files in the folder "Display Templates/Style Sheets" that were created before 2020 to /my-exports
corso export sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
--file-created-before 2020-01-01T00:00:00 --folder "Display Templates/Style Sheets" my-exports
# Export all files in the "Documents" library to current directory.
corso export sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd
# Export all files in the "Documents" library to the current directory.
corso export sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
--library Documents --folder "Display Templates/Style Sheets" .`
)

Expand Down
12 changes: 5 additions & 7 deletions src/cli/restore/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func addGroupsCommands(cmd *cobra.Command) *cobra.Command {

switch cmd.Use {
case restoreCommand:
c, fs = utils.AddCommand(cmd, groupsRestoreCmd(), utils.MarkPreReleaseCommand())
c, fs = utils.AddCommand(cmd, groupsRestoreCmd(), utils.MarkPreviewCommand())

c.Use = c.Use + " " + groupsServiceCommandUseSuffix

Expand All @@ -40,24 +40,22 @@ func addGroupsCommands(cmd *cobra.Command) *cobra.Command {
return c
}

// TODO: correct examples
const (
groupsServiceCommand = "groups"
teamsServiceCommand = "teams"
groupsServiceCommandUseSuffix = "--backup <backupId>"

groupsServiceCommandRestoreExamples = `# Restore file with ID 98765abcdef in Bob's last backup (1234abcd...)
groupsServiceCommandRestoreExamples = `# Restore file with ID 98765abcdef in Marketing's last backup (1234abcd...)
corso restore groups --backup 1234abcd-12ab-cd34-56de-1234abcd --file 98765abcdef
# Restore the file with ID 98765abcdef along with its associated permissions
corso restore groups --backup 1234abcd-12ab-cd34-56de-1234abcd --file 98765abcdef --restore-permissions
# Restore files named "FY2021 Planning.xlsx" in "Documents/Finance Reports"
corso restore groups --backup 1234abcd-12ab-cd34-56de-1234abcd \
--file "FY2021 Planning.xlsx" --folder "Documents/Finance Reports"
# Restore all files named "FY2021 Planning.xlsx"
corso restore groups --backup 1234abcd-12ab-cd34-56de-1234abcd --file "FY2021 Planning.xlsx"
# Restore all files and folders in folder "Documents/Finance Reports" that were created before 2020
corso restore groups --backup 1234abcd-12ab-cd34-56de-1234abcd
corso restore groups --backup 1234abcd-12ab-cd34-56de-1234abcd \
--folder "Documents/Finance Reports" --file-created-before 2020-01-01T00:00:00`
)

Expand Down
2 changes: 1 addition & 1 deletion src/cli/restore/onedrive.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ corso restore onedrive --backup 1234abcd-12ab-cd34-56de-1234abcd \
--file "FY2021 Planning.xlsx" --folder "Documents/Finance Reports"
# Restore all files and folders in folder "Documents/Finance Reports" that were created before 2020
corso restore onedrive --backup 1234abcd-12ab-cd34-56de-1234abcd
corso restore onedrive --backup 1234abcd-12ab-cd34-56de-1234abcd \
--folder "Documents/Finance Reports" --file-created-before 2020-01-01T00:00:00`
)

Expand Down
10 changes: 1 addition & 9 deletions src/cli/restore/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package restore

import (
"context"
"os"

"github.com/alcionai/clues"
"github.com/pkg/errors"
Expand All @@ -20,9 +19,7 @@ var restoreCommands = []func(cmd *cobra.Command) *cobra.Command{
addExchangeCommands,
addOneDriveCommands,
addSharePointCommands,
// awaiting release
// addGroupsCommands,
// addTeamsCommands,
addGroupsCommands,
}

// AddCommands attaches all `corso restore * *` commands to the parent.
Expand All @@ -33,11 +30,6 @@ func AddCommands(cmd *cobra.Command) {
for _, addRestoreTo := range restoreCommands {
addRestoreTo(restoreC)
}

// delete after release
if len(os.Getenv("CORSO_ENABLE_GROUPS")) > 0 {
addGroupsCommands(restoreC)
}
}

const restoreCommand = "restore"
Expand Down
4 changes: 2 additions & 2 deletions src/cli/restore/sharepoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
--file "ServerRenderTemplate.xsl" --folder "Display Templates/Style Sheets"
# Restore all files in the folder "Display Templates/Style Sheets" that were created before 2020.
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
--file-created-before 2020-01-01T00:00:00 --folder "Display Templates/Style Sheets"
# Restore all files in the "Documents" library.
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
--library Documents --folder "Display Templates/Style Sheets" `
)

Expand Down
15 changes: 15 additions & 0 deletions src/cli/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func HasNoFlagsAndShownHelp(cmd *cobra.Command) bool {
type cmdCfg struct {
hidden bool
preRelease bool
preview bool
}

type cmdOpt func(*cmdCfg)
Expand All @@ -161,6 +162,12 @@ func MarkPreReleaseCommand() cmdOpt {
}
}

func MarkPreviewCommand() cmdOpt {
return func(cc *cmdCfg) {
cc.preview = true
}
}

// AddCommand adds a clone of the subCommand to the parent,
// and returns both the clone and its pflags.
func AddCommand(parent, c *cobra.Command, opts ...cmdOpt) (*cobra.Command, *pflag.FlagSet) {
Expand All @@ -178,6 +185,14 @@ func AddCommand(parent, c *cobra.Command, opts ...cmdOpt) (*cobra.Command, *pfla
"==================================================================================================\n"
}

if cc.preview {
// There is a default deprecated message that always shows so we do some terminal magic to overwrite it
c.Deprecated = "\n\033[1F\033[K" +
"=============================================================================================================\n" +
"\tWARNING!!! THIS IS A FEATURE PREVIEW THAT MAY NOT FUNCTION PROPERLY AND MAY BREAK ACROSS RELEASES\n" +
"=============================================================================================================\n"
}

c.Flags().SortFlags = false

return c, c.Flags()
Expand Down
13 changes: 12 additions & 1 deletion src/cmd/mdgen/mdgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func fatal(err error) {
// Adapted from https://github.com/spf13/cobra/blob/main/doc/md_docs.go for Corso specific formatting
func genMarkdownCorso(cmd *cobra.Command, dir string) error {
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
if !isAvailableCommand(c) || c.IsAdditionalHelpTopicCommand() {
continue
}

Expand All @@ -116,6 +116,17 @@ func genMarkdownCorso(cmd *cobra.Command, dir string) error {
return genMarkdownCustomCorso(cmd, f)
}

// adapted from cobra.Command.IsAvailablecommand()
func isAvailableCommand(cmd *cobra.Command) bool {
return cmd.IsAvailableCommand() ||
// exception case to the cobra isAvailable:
// preview commands hijack the "deprecated"
// value, but are not hidden. In order for
// this to work, we'll need to hide any commands
// that we deprecate.
(len(cmd.Deprecated) > 0 && !cmd.Hidden)
}

func genMarkdownCustomCorso(cmd *cobra.Command, w io.Writer) error {
cmd.InitDefaultHelpCmd()
cmd.InitDefaultHelpFlag()
Expand Down
4 changes: 3 additions & 1 deletion website/docs/developers/linters.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ cryptic messages how you can fix the problems the linters flag.
Each subsection also includes the version of golangci-lint it applies to and the
linter in question.

### `gci` `Expected 's', Found 'a' at file.go`
```sh
gci Expected 's', Found 'a' at file.go
```

This applies to golangci-lint v1.45.2 for the `gci` linter and is due to an import
ordering issue. It occurs because imports in the file aren't grouped according
Expand Down
2 changes: 1 addition & 1 deletion website/docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,5 +339,5 @@ See [here](../setup/restore-options) for more restoration options.
The above tutorial only scratches the surface for Corso's capabilities. We encourage you to dig deeper by:

* Learning about [Corso concepts and setup](../setup/concepts)
* Explore Corso backup and restore options for Exchange and Onedrive in the [Command Line Reference](../cli/corso)
* Explore Corso backup and restore options for M365 Applications in the [Command Line Reference](../cli/corso)
* Leverage Corso's [Advanced Restoration Options](../setup/restore-options)
7 changes: 7 additions & 0 deletions website/docs/setup/m365-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,18 @@ then click **Add permissions**.
| API / Permissions Name | Type | Description
|:--|:--|:--|
| Calendars.ReadWrite | Application | Read and write calendars in all mailboxes |
| ChannelMessage.Read.All | Application | Read all messages in Teams' channels |
| ChannelSettings.Read.All | Application | Read all Teams' channel settings |
| Chat.Read.All | Application | Read all Teams' chats and chat messages |
| Contacts.ReadWrite | Application | Read and write contacts in all mailboxes |
| Directory.Read.All | Application | Read all organization directory data |
| Files.ReadWrite.All | Application | Read and write files in all site collections |
| MailboxSettings.Read | Application | Read all user mailbox settings |
| Mail.ReadWrite | Application | Read and write mail in all mailboxes |
| Member.Read.Hidden | Application | Read hidden group memberships |
| Sites.FullControl.All | Application | Have full control of all site collections |
| TeamMember.Read.All | Application | Read all Teams' user memberships |
| TeamSettings.Read.All | Application | Read all Teams' settings |
| User.Read.All | Application | Read all users' full profiles |

<!-- vale Microsoft.Spacing = YES -->
Expand Down
Loading

0 comments on commit a60d599

Please sign in to comment.