Azure Batch - Setting custom user identity for tasks - azure-batch

I am using Azure Batch C# Client API 6.1. I am trying to have all my runs using the same user identity.
I am setting a custom user identity as below, as per MSDN documentation.
var task = new CloudTask("{guid}", "command string")
{
DisplayName = "display name",
UserIdentity = new UserIdentity("customUserid")
}
However when the job runs, the task executes under a random user account.
Would anyone know how to make it work OR even if it is supported by the backend Azure Batch service?
Thanks in advance

In order to use named user accounts, you need to first specify a list of UserAccount on your CloudPool during creation.
pool.UserAccounts = new List<UserAccount>
{
new UserAccount("myadminaccount", "adminpassword", ElevationLevel.Admin),
new UserAccount("mynonadminaccount", "nonadminpassword", ElevationLevel.NonAdmin),
};
You will then be able to execute tasks assigned to this pool with UserIdentity properties as you have in your example.
Unfortunately the MSDN documentation for this feature is lagging behind currently, but should be updated soon.

Related

How do I give Permissions using Azure DevOps Server Rest APi

https://learn.microsoft.com/en-us/rest/api/azure/devops/security/?view=azure-devops-server-rest-5.0
https://learn.microsoft.com/en-us/rest/api/azure/devops/security/access%20control%20entries?view=azure-devops-server-rest-5.0
Hi there, I'm having problems with trying to understand the way to set up permissions using the API in ADO 2019. I can see what the security namespace one API does. I can get bitwise that relates to, for examples, git repos. I can't see how to add permissions to a user or group. e.g. I can't see how to get a bitwise that has multiple permissions, do I just add them together? I can see the API that says how to add ACEs but that doesn't actually tell me how to add permissions really. I'll try to explain.
If I run the API for ACL , I get a pile of info back, one of which is token.
Okay, so surely if I get the GUID for the git repo using the git API to list them, the GUID will match up with the ID's in the token like the namespaces do. Nope.
The examples don't seem to be actual examples. I'm looking for 'If you have a git repo , here's how you would give someone permissions to it' 'here's an example of getting the existing permissions for a group and adding another'.
Instead it's just
'here's a string of guids getting put into the API' without explaining the pieces or what specifically it was doing. I can't seem to relate what's in the GUI for adding perms, to what the security API is bringing back.
Am Azure DevOps on prem so I'm more limited in tool selection. Other people I've asked say they gave up trying to use this. AzureDevops on twitter says I can connect with the team here. I'm asking how to do things with the security API and then I can go write it up and suggest how to update the docs. I'm clearly too thick to figure it out from what's there and I don't seem to be the only one. Thanks
For Azure DevOps Service, you can manage group membership using Graph API. But this api is not available for Azure DevOps Server.
In my opinion, for on-premise TFS/Azure DevOps Server, TFSSecurity command line is easier than TFS API to add permissions for a user or a group in a server-level, collection-level, or project-level group. You may consider using TFSSecurity command line:
https://learn.microsoft.com/en-us/azure/devops/server/command-line/tfssecurity-cmd?view=azure-devops-2019
You may also check the following code to get the permissions:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Framework.Client;
namespace API
{
class Program
{
static void Main(string[] args)
{
string project = "http://xxx.xxx.xxx.xxx:8080/tfs";
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project));
var tps = tpc.GetService<VersionControlServer>();
var ttt = tps.GetTeamProject("ProjectName");
ISecurityService securityService = tpc.GetService<ISecurityService>();
System.Collections.ObjectModel.ReadOnlyCollection<SecurityNamespace> securityNamespaces = securityService.GetSecurityNamespaces();
IGroupSecurityService gss = tpc.GetService<IGroupSecurityService>();
Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "GroupName", QueryMembership.Expanded);//GourName format: [ProjectName]\\GourpName
IdentityDescriptor id = new IdentityDescriptor("Microsoft.TeamFoundation.Identity", SIDS.Sid);
List<SecurityNamespace> securityList = securityNamespaces.ToList<SecurityNamespace>();
string securityToken;
foreach (SecurityNamespace sn in securityList)
{
if (sn.Description.DisplayName == "Project")
{
securityToken = "$PROJECT:" + ttt.ArtifactUri.AbsoluteUri;
sn.SetPermissions(securityToken, id, 115, 0, true);
}
}
}
}
}

Add member to Azure DevOps team

I've able to get team or team member but I could not find away to add user to the team. Is there RESt_API, command line, or API that I could add user to the team using domain name "domain\user". Please advise. Great appreciate
Best Regards,
If you use Azure DevOps Service (https://dev.azure.com/xxxx), you could use Members - Add REST API.
If you use Azure DevOps Server, the REST API to add members to projects and team is not documented. As a workaround, we can track this rest api by pressing F12 in browser then select Network.
Sample:
POST http://TFS2019:8080/tfs/{Collection}/{project}/_api/_identity/AddIdentities?api-version=5.0
Request Body:
{
"newUsersJson": "[]",
"existingUsersJson": "[\"55b98726-c6f5-48d2-976b-xxxxxx\"]",
"groupsToJoinJson": "[\"7283653f-54b2-4ebf-86c3-xxxxxxx\"]",
"aadGroupsJson": "[]"
}
However as we can see we can only use the user and team/group GUID in the request json body. For the specific team/groups we can use the REST APIs Projects and teams to get their GUID.
For the user, actually it's used the TeamFoundationId, the unique TeamFoundationId is automatically generated when a user is added to Azure DevOps Server. We cannot generate the ID with external tools.
So, to use that REST API, we need to get the TeamFoundationId of the specific user which you want to add it to the projects/teams.
Currently, no REST API to list TeamFoundationId of the users in Azure DevOps Server 2019, however we can get it with Client API:
Below sample for your reference to get the TeamFoundationId of a specific user: (It will also export the user list with their TeamFoundationId to userlist.txt)
using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using System.Linq;
using System.IO;
namespace Getuserlist
{
class Program
{
static void Main(string[] args)
{
TfsConfigurationServer tcs = new TfsConfigurationServer(new Uri("https://wsicads2019"));
IIdentityManagementService ims = tcs.GetService<IIdentityManagementService>();
TeamFoundationIdentity tfi = ims.ReadIdentity(IdentitySearchFactor.AccountName, "[DefaultCollection]\\Project Collection Valid Users", MembershipQuery.Expanded, ReadIdentityOptions.None);
TeamFoundationIdentity[] ids = ims.ReadIdentities(tfi.Members, MembershipQuery.None, ReadIdentityOptions.None);
using (StreamWriter file = new StreamWriter("userlist.txt"))
foreach (TeamFoundationIdentity id in ids)
{
if (id.Descriptor.IdentityType == "System.Security.Principal.WindowsIdentity" && id.UniqueName == "Domain\\User")
{ Console.WriteLine("[{0},{1}]", id.UniqueName, id.TeamFoundationId); }
file.WriteLine("[{0},{1}]", id.UniqueName, id.TeamFoundationId);
}
var count = ids.Count(x => ids.Contains(x));
Console.WriteLine(count);
Console.ReadLine();
}
}
}

Get triggered rule names which is executing on decision server from client side (Redhat Decision Manager)

I am using the REST api for executing rules on Decision Server (Redhat Decision Manager 7.2) using a stateless kie session. I'm currently getting the number of triggered rules, but I also want to get the names of those rules. Is this possible?
KieServicesConfiguration conf = KieServicesFactory.newRestConfiguration(URL, USER, PASSWORD);
List<GenericCommand<?>> commands = new ArrayList<GenericCommand<?>>();
commands.add((GenericCommand<?>)
KieServices.Factory.get().getCommands().newInsert(applicant, "applicant"));
commands.add((GenericCommand<?>)
KieServices.Factory.get().getCommands().newInsert(loan, "loan"));
commands.add((GenericCommand<?>)KieServices.Factory.get().getCommands().newFireAllRules("numberOfFiredRules"));
KieCommands kieCommands = KieServices.Factory.get().getCommands();
BatchExecutionCommand batchCommand = kieCommands.newBatchExecution(commands, "default-stateless-ksession");
ServiceResponse<ExecutionResults> executeResponse = ruleServicesClient
.executeCommandsWithResults("loan-application_1.2.0", batchCommand);
System.out.println("Number of fired rules:" executeResponse.getResult().getValue("numberOfFiredRules"));
You have to use an AgendaEventListener to keep track of rules exectioned. By implemnting org.kie.api.event.rule.AgendaEventListener interface you can capture these detials.
To know which rules are triggered I added an action column with custom code (Action BRL fragment) that writes the rule name in one of the field of my fact. You can get it from rule.name.
Example:myFact.logMyRuleName(rule.name)

How to publish a draft Task Group via Azure DevOps API

I am in the process of converting some tasks inside numerous task groups we have to different tasks. Instead of doing this by hand I've opted for using Powershell along with the Rest API of Azure DevOps to update the JSON bodies of these task groups and send them to the API. The conversion of the tasks is working fine sofar.
sending a PUT to the rest API in order to update the current task group of the set works but I want to build in some retention / version history if some of the new tasks end up working different than expected. So just blatantly updating the existing Task Group under the same major version is not an option.
the UI of Azure DevOps has functionality where you can save changes to a task group as a 'draft' and then publish this draft as either a completely new version (major version + 1) or as a preview
I went ahead and attempted to send a PUT to the Rest API and upticking the major version using the following URI:
PUT https://dev.azure.com/{organization}/{project}/_apis/distributedtask/taskgroups/{taskGroupId}?api-version=5.1-preview.1
Along with the settings:
JSONObject.version.major = $currentversion + 1
JSONObject.preview = true
This results in the API returning an error saying:
Invoke-WebRequest : {"$id":"1","innerException":null,"message":"Task group {TaskGroupID} not found.","typeName":"Microsoft.TeamFoundation.DistributedTask.WebApi.MetaTaskDefinitionNotFoundException, Microsoft.TeamFoundation.DistributedTask.WebApi","type
Key":"MetaTaskDefinitionNotFoundException","errorCode":0,"eventId":3000}
I then went ahead and tried to see if I could create a draft version. When sending a POST to the following URI i was able to create a draft:
POST https://dev.azure.com/{organization}/{project}/_apis/distributedtask/taskgroups?api-version=5.1-preview.1
using the following settings in JSON:
JSONObject.version.major = 1
JSONObject.version.istest = true
JSONObject.id = $null
JSONObject.parentDefinitionId = {TaskGroupID of the taskgroup of which i am trying to make a draft}
This nets in a new Task group in draft state which i am able to view in the UI and modify and publish (with or without preview). When i export the created JSON from UI from a manually made draft and compare it versus the one coming from powershell i see no differences.
This last step is where I am stuck. I can't seem to convert the created draft into a new version of the {parentdefintionid} task group. I've tried the following settings:
Calling the taskgroupid URI of the parent with put while a draft is available
JSONObject.version.major = $currentversion + 1
JSONObject.version.isTest = false
JSONObject.preview = true
Removing ParentDefinitionID from JSONObject
is resulting in the same error where it states that it cannot find the ID of the parent:
Invoke-WebRequest : {"$id":"1","innerException":null,"message":"Task group {TaskGroupID} not found.","typeName":"Microsoft.TeamFoundation.DistributedTask.WebApi.MetaTaskDefinitionNotFoundException, Microsoft.TeamFoundation.DistributedTask.WebApi","type
Key":"MetaTaskDefinitionNotFoundException","errorCode":0,"eventId":3000}
The same is valid with above settings and calling the draftID URI
When i try to call the draftID task group URI with the following settings :
JSONObject.version.major = $currentversion + 1
JSONObject.version.isTest = false
JSONObject.preview = true
JSONObject.id = $ParentDefinitionID
Removing ParentDefinitionID from JSONObject
it results in the following error:
Invoke-WebRequest : {"$id":"1","innerException":null,"message":"The request specifies task group ID {parentTaskGroupID} but the supplied task group has ID {DraftTaskGroupID}.","typeName":"Microsoft.TeamFoundation.DistributedTask.WebApi.Task
GroupIdConflictException, Microsoft.TeamFoundation.DistributedTask.WebApi","typeKey":"TaskGroupIdConflictException","errorCode":0,"eventId":3000}
i've checked the actual JSONObject to an export of a published Task Group in UI and they match exactly so i'm quite positive that content is not the issue here.
The MS documentation is seriously lacking on API usage so i'm really in the dark there hoping to find some clues / solution here
Seems you were updating a already exist task group in Azure DevOps.
If you incremented the revision property to be 1 higher than what is currently deployed.
You need to submit the JSON with the same revision property that the server has.

Specify Google Task ID on insert

I am working with Google Tasks, using the PHP library:
https://developers.google.com/tasks/v1/reference/tasks
I am trying to insert a task with a custom ID.
I found this topic:
Setting id to task using Google Task API returns 400 invalid value
which points to this topic:
Google tasks update error
They suggest to send the Task ID with the Task title. I think I have done that.
This is the code info from the Google API reference
$task = new Task();
$task->setTitle('New Task');
$task->setNotes('Please complete me');
$task->setDue(new TaskDateTime('2010-10-15T12:00:00.000Z'));
$result = $service->insertTasks('#default', $task);
echo $result->getId();
This is my code, I got setID() from the library itself.
$taskNew = new Google_Service_Tasks_Task();
$taskNew->setId('2013');
$taskNew->setTitle('Notify');
$taskNew->setDue(new TaskDateTime('2018-10-27T00:00:00.000Z'));
$results3 = $service->tasks->insert('.....', $taskNew);
I keep getting an error and it refuses to make the task.
Using this API tool:
https://developers.google.com/apis-explorer/#p/tasks/v1/tasks.tasks.insert
I can insert tasks successfully, so long as the system makes the ID. The Google Task API will insert the task, but assign its own ID.
If I specify a custom ID, then I get a 400 error "Invalid value".
I am making tasks to correspond to events saved in my program's database. I need to be able to find the task that matches a database event when I need to make changes to the due date or completed.
The reason I want to set my own ID, is so I can find the specific task and make changes.
I could add a new field to the database with the ID that google generates. But I would prefer to not have to change the database and the rest of the program as well.
Thanks so much for any help,
- Jon
Task Id is the read-only parameter.
I solved this question by using a prefix for the task`s Title.
For example: "[my_id] Task Title".