pnp / cli-microsoft365

Manage Microsoft 365 and SharePoint Framework projects on any platform
https://aka.ms/cli-m365
MIT License
925 stars 325 forks source link

Create Planner roster commands #4383

Closed milanholemans closed 1 year ago

milanholemans commented 1 year ago

The idea is to add a few commands to work with Planner rosters.

New commands

Update commands

All these commands commands will use Graph beta API since this isn't available in v1.0 yet. So let's not forget to add a remark to the docs stating that these commands use an API that is subject to change.

Update commands (next phase)

For the commands below, we should also introduce a now option rosterId.

Graph docs

https://learn.microsoft.com/en-us/graph/api/resources/plannerroster?view=graph-rest-beta

milanholemans commented 1 year ago

@pnp/cli-for-microsoft-365-maintainers do you agree to add these? If so, I'll spec them out.

waldekmastykarz commented 1 year ago

Great suggestion @milanholemans! Could you please clarify the purpose of the rosterId option on existing planner plan commands?

milanholemans commented 1 year ago

Great suggestion @milanholemans! Could you please clarify the purpose of the rosterId option on existing planner plan commands?

Sure! Right now it's only possible to do CRUD operations on Planner plans that are contained in an O365 group. So ownerGroupId or ownerGroupName are 2 required options there. I think we should add an extra option rosterId so people can use these commands as well for Plans that are contained in a Planner roster instead of an O365 group.

waldekmastykarz commented 1 year ago

Understood, so roster is basically an alternative container for a plan and when referring to one, you'd specify either the group or the roster. Makes sense. Thank you for clarifying. Let's be sure we explain this properly in the docs. Would it btw. also make sense to allow users to reference a roster by its name (assuming it's got one) for convenience?

milanholemans commented 1 year ago

Understood, so roster is basically an alternative container for a plan and when referring to one, you'd specify either the group or the roster.

Correct! Roster is a container where you can store Planner plans without the need to create a new O365 group (with mailbox, SP site, ...)

Let's be sure we explain this properly in the docs.

Yes indeed, we should add a link to a page where they explain what a roster is.

Would it btw. also make sense to allow users to reference a roster by its name (assuming it's got one) for convenience?

Weirdly enough, a roster has no name. Only an ID. Example of a roster object:

image

Therefore I'm not sure if we should add the roster get command since the response is quite poor. Only benefit you get is that you have a property called assignedSensitivityLabel which might be useful for some people?

Also it seems to be impossible to list all rosters within a tenant (why tho?). That's why I didn't include a roster list command.

waldekmastykarz commented 1 year ago

Thanks for the additional data. If there's no ability to list rosters, how would you get one's ID for use with other commands? 🤔

milanholemans commented 1 year ago

Thanks for the additional data. If there's no ability to list rosters, how would you get one's ID for use with other commands? 🤔

Good question, as far as I know, when retrieving a plan, you have an extra property now called container:

image

The ID of the container is the ID of the roster. Not sure if there are other ways to retrieve the ID of a roster.

Jwaegebaert commented 1 year ago

Looks like some new stuff has been added to Planner. Nice work with this epic!

For the command planner roster get, I think it would be better to put that on hold until it returns more information and we have access to a sort of list endpoint for the roster objects. That way we don't clutter that object with commands that don't have a compelling use case yet.

waldekmastykarz commented 1 year ago

@milanholemans, how can you tell if the container is a group or a roster, based on its URL? If you get the roster's ID from a plan's container, does the get roster API return any more information? If the information is the same as in the container property, then there would be no value of having roster get, because by the time you get the roster's ID, you've got all the information.

milanholemans commented 1 year ago

@milanholemans, how can you tell if the container is a group or a roster, based on its URL?

You can determine it based on the URL indeed, but there's also another way. For a Plan within a group the container property looks like:

"container": {
      "containerId": "ebf3b108-5234-4e22-b93d-656d7dae5874",
      "type": "group",
      "url": "https://graph.microsoft.com/v1.0/groups/ebf3b108-5234-4e22-b93d-656d7dae5874"
    }

For a Plan within a roster the container property looks like:

"container": {
        "containerId": "tYqYlNd6eECmsNhN_fcq85cAGAnd",
        "type": "unknownFutureValue",
        "url": "https://graph.microsoft.com/v1.0/planner/rosters/tYqYlNd6eECmsNhN_fcq85cAGAnd"
    }

So with the type property you can tell if the plan is within a group or a roster. I guess the current value unknownFutureValue will change to roster in the future.

If you get the roster's ID from a plan's container, does the get roster API return any more information? If the information is the same as in the container property, then there would be no value of having roster get, because by the time you get the roster's ID, you've got all the information.

When retrieving a roster, the only additional info you get is assignedSensitivityLabel. However I'm not sure if this is useful enough to create a roster get command.

{
   "id": "tYqYlNd6eECmsNhN_fcq85cAGAnd",
   "assignedSensitivityLabel": null
} 
martinlingstuyl commented 1 year ago

When retrieving a roster, the only additional info you get is assignedSensitivityLabel. However I'm not sure if this is useful enough to create a roster get command.

This might become useful when we have more commands for information protection. I'd say: just create the spec and let's implement it. The output might grow in the coming months, which is nice for us.

By the way: do we also have the ability to set the sensitivityLabel on a roster? In that case it's extra important to also have the get to read it out.

milanholemans commented 1 year ago

By the way: do we also have the ability to set the sensitivityLabel on a roster? In that case it's extra important to also have the get to read it out.

Not sure, according to the docs this seems impossible. For the create API I read: There are no writable properties on a plannerRoster object. Also this property is nowhere listed in the Graph docs.

Jwaegebaert commented 1 year ago

I also didn't find any documentation regarding the sensitivityLabel being available for the roster object. As they are still working on the roster aspect, I would say that we wait until there is more information available.

waldekmastykarz commented 1 year ago

Nice research @milanholemans. Let's introduce roster get and let's use the type from container to determine which container we're dealing with, assuming for now that unknownFutureValue means roster.

milanholemans commented 1 year ago

Specced out the first few commands.

Also noticed that for an M365 group it's possible to create multiple plans within the same group. However a Planner Roster can contain only 1 plan. If you try to add multiple plans you get this very unclear error: You do not have the required permissions to access this item, or the item may not exist.

waldekmastykarz commented 1 year ago

If you try to add multiple plans you get this very unclear error: You do not have the required permissions to access this item, or the item may not exist.

That's a bummer. Almost makes me think to look at the error if any, and if it matches what you shared, do an extra request to compare the name and fail with a meaningful error instead.