I am running several YAML pipelines and use variable groups for this. I have a number of variable groups and each needs to be linked to a keyvault, and all secrets in that keyvault need to be added to the variable group.
In the documentation (variablegroup documentation) it only gives the option to click on the "+Add" button and select each secret by hand. This takes up a lot of time, since there are a lot of secrets that need to be added.
Does anyone know of an option to select all secrets in a keyvault to add to a variable group?
Preferably from a powershell or CLI script.
Thanks for your help!
[EDIT]: I apologize for the confusing use of the word "secrets" before. I am looking to link the variable group to a KeyVault and add the secrets that are in there.
You can use the REST API Variablegroups - Update to batch set variables in a variable group.
PUT https://dev.azure.com/{organization}/_apis/distributedtask/variablegroups/{groupId}?api-version=6.0-preview.2
P.S. The id of a variable group is an integer and increase from 1 in the order they were created. You can aslo get the id of a variable group using the REST API Variablegroups - Get Variable Groups
GET https://dev.azure.com/{organization}/{project}/_apis/distributedtask/variablegroups?api-version=6.0-preview.2
to get all variable groups of your project and find the specific variable group id that you want.
Here is an example of the REST API's request body:
{
"name": "{variable group name}",
"variables": {
"A": {
"isSecret": false,
"value": "a"
},
"B": {
"isSecret": true,
"value": "b"
},
"C": {
"isSecret": true,
"value": "c"
}
},
"variableGroupProjectReferences": [
{
"description": "",
"name": "{variable group name}",
"projectReference": {
"id": "",
"name": "{project name}"
}
}
]
}
Related
I've created a CloudFormation template that successfully creates an IAM user and an AccessKey and assigns that AccessKey to the IAM user. Right now I am getting the AccessKey's secret by outputting it in the Outputs section of the CloudFormation template.
I'd like to know if there is a more secure way to create the AccessKey and fetch its corresponding secret without spitting it out in plain text in the Outputs section.
I'm a bit confused by this because AWS doesn't have much info on doing this, and what little docs it does have directly contradict each other. Here AWS suggests doing what I've described above "One way to retrieve the secret key is to put it into an Output value". This seems like a security issue, and is confirmed by another AWS doc Here where it says "We strongly recommend you don't use this section to output sensitive information, such as passwords or secrets".
Am I misunderstanding their documentation or is this a direct contradiction? I've seen a S/O comment Here suggesting the use of AWS secrets manager but I'm having trouble figuring out how to get the AccessKey secret into Secrets Manager, where it can be stored and fetched more securely by something like boto3. Any example of this would be super helpful. My CloudFormation template is below for reference.
{
"Description": "My CloudFormation Template",
"Outputs": {
"UserAccessKeyId": {
"Description": "The value for the User's access key id.",
"Value": {
"Ref": "UserAccessKey"
}
},
"UserSecretKey": {
"Description": "The value for the User's secret key.",
"Value": {
"Fn::GetAtt": [
"UserAccessKey",
"SecretAccessKey"
]
}
}
},
"Resources": {
"User": {
"Properties": {
"UserName": "myNewUser"
},
"Type": "AWS::IAM::User"
},
"PrimaryUserAccessKey": {
"DependsOn": "User",
"Properties": {
"Status": "Active",
"UserName": "myNewUser"
},
"Type": "AWS::IAM::AccessKey"
}
}
}
I would recommend putting it in a Secret. You can have the CloudFormation write the value to Secrets Manager in the stack, and then you can access it via code. That allows you to have a secret that no person has to see or touch to use it.
I think something like this should work (note: I haven't actually tried this).
AccessKey:
Type: AWS::IAM::AccessKey
Properties:
Serial: 1
Status: Active
UserName: 'joe'
AccessKeySecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: JoeAccessKey
Description: Joes Access Key
SecretString: !Sub '{"AccessKeyId":"${AccessKey}","SecretAccessKey":"${AccessKey.SecretAccessKey}"}'
I have a requirement to dynamically add/remove or enable disable approval and checks at azure DevOps pipeline environment.
Is there a rest api for this?
Is there a rest api for this?
Yes, it has. BUT, as what the #Krysztof said, we haven't provide such api documents to public as of today. This is because what you are looking for is one feature (configure Check and approval from environments ) that only support for YAML pipeline, and until now, we are developing but does not publish the corresponding rest api (for YAML) docs.
But, as work around, you can catch these apis from F12. Just do action from UI, then capture and analyze corresponds api records to found out what you are expecting.
Here I make the summary to you.
The api that used to add/delete approval and check to environment is:
https://dev.azure.com/{org name}/{project name}/_apis/pipelines/checks/configurations
The corresponding api method for add or delete is Post and DELETE.
Firstly, share you the request body samples which for approval and check added.
1) Add approval to this environment:
{
"type": {
"id": "8C6F20A7-A545-4486-9777-F762FAFE0D4D", // The fixed value for Approval
"name": "Approval"
},
"settings": {
"approvers": [
{
"id": "f3c88b9a-b49f-4126-a4fe-3c99ecbf6303" // User Id
}
],
"executionOrder": 1,
"instructions": "",
"blockedApprovers": [],
"minRequiredApprovers": 0,
"requesterCannotBeApprover": false // The pipeline requester allow to approve it.
},
"resource": {
"type": "environment",
"id": "1", // Environment id
"name": "Deployment" //Environment name
},
"timeout": 43200 // Set the available time(30d) of this approval pending. The measure unit is seconds.
}
2) Add task check, Azure function, Invoke rest api task and etc:
{
"type": {
"id": "fe1de3ee-a436-41b4-bb20-f6eb4cb879a7", // Fixed value if you want to add task check
"name": "Task Check" //Fixed value
},
"settings": {
"definitionRef": {
"id": "537fdb7a-a601-4537-aa70-92645a2b5ce4", //task Id
"name": "AzureFunction", //task name
"version": "1.0.10" //task version
},
"displayName": "Invoke Azure Function", //task display name configured
"inputs": {
"method": "POST",
"waitForCompletion": "false",
"function": "csdgsdgsa",
"key": "436467543756" // These are all task inputs
},
"retryInterval": 5, // The re-try time specified.
"linkedVariableGroup": "AzKeyGroup"// The variable group name this task linked with
},
"resource": {
"type": "environment",
"id": "2",
"name": "Development"
},
"timeout": 43200
}
In this request body, you can find the corresponding task id from our public source code. Just check the task.json file of corresponding task.
3) Add template check:
{
"type": {
"id": "4020E66E-B0F3-47E1-BC88-48F3CC59B5F3", // Fixed value for template check added.
"name": "ExtendsCheck" //Fixed value
},
"settings": {
"extendsChecks": [
{
"repositoryType": "git", // github for Github source, bitbucket for Bitbucket source
"repositoryName": "MonnoPro",
"repositoryRef": "refs/heads/master",
"templatePath": "tem.yml"
}
]
},
"resource": {
"type": "environment",
"id": "6",
"name": "development"
}
}
In this body, if the template source is coming from github or bitbucket, the value of repositoryName should like {org name}/{repos name}.
Hope these are helps.
This is an older question but we had a similar need. There does not appear to be a direct API To query this, but this GitHub Project pointed us in the right direction:
# GET ENVIRONMENT CHECKS (stored under .fps.dataProviders.data['ms.vss-pipelinechecks.checks-data-provider'].checkConfigurationDataList)
GET https://dev.azure.com/{{organization}}/{{project}}/_environments/{{environment_id}}/checks?__rt=fps&__ver=2
As mentioned above under .fps.dataProviders.data['ms.vss-pipelinechecks.checks-data-provider'].checkConfigurationDataList the list of who is authorized is provided.
The officially documented APIs can tell you that there are checks in place; for example:
GET https://dev.azure.com/{organization}/{project}/_apis/pipelines/checks/configurations?resourceType=environment&resourceId={id}
Can tell you that you have checks enabled (including an Approval check) but this isn't super useful as it does not give a list of who can Approve.
Note that you can get the list of environments (to get their resource ID) using this documented API:
GET https://dev.azure.com/{organization}/{project}/_apis/distributedtask/environments?api-version=7.1-preview.1
This is not supported at the moment. You can upvote feature request to show your interest here.
Context
I'm developing a custom service in a .Net MVC Web Application that will connect to an OTRS web service to create/list/update tickets.
We are implementing many process workflows to make things works more efficiently.
Problem
I cannot find a way to "attach" a new ticket to a process, I know how to create a normal ticket, but not a process ticket.
I found a perl script that seems to do what I need to, but I cannot find a way to connect the problem with the solution.
Perl Script
ProcessTicketProcessSet()
Set Ticket's ProcessEntityID
my $Success = $ProcessObject->ProcessTicketProcessSet(
ProcessEntityID => 'P1',
TicketID => 123,
UserID => 123,
);
Returns:
$Success = 1; # undef
1 if setting the Activity was executed
undef if setting failed
Normal Ticket
URL:
http://someDomain.com.br/otrs/nph-genericinterface.pl/Webservice/SomeWebServiceName/Ticket?UserLogin=user&Password=abcd
Method: POST
Body:
{
"UserLogin": "user",
"Password": "abcd",
"Ticket": {
"Title": "REST - To Create Ticket",
"Type": "Unclassified",
"QueueID": "5",
"State": "new",
"Priority": "3 normal",
"CustomerUser": "someuser#someemail.com.br"
},
"DynamicField": [{
"Name": "CustomFieldOne",
"Value": "value1"
},
{
"Name": "CustomFieldTwo",
"Value": "value2"
}
],
"Article": {
"Subject": "Rest - Article Ticket",
"Body": "Test Article Creation",
"ContentType": "text/plain; charset=utf8"
}
}
How can I create a ticket that belongs to a process?
To create a ticket which belongs to a process you need to set two dynamic fields of a ticket.
ProcessManagementProcessID (which is representing the process)
ProcessManagementActivityID (which is representing the activity step of the process)
In case you also can set both dynamic fields later to set the process.
In case you do not know what values you need to set, just launch a process ticket via the UI and check via the ticket histories what values are set for both dynamic fields.
I have an endpoint /groups
I can create a group by POSTing some info to /groups
A single group can be read by /groups/{id}
I can update some fields in the group by POSTing to /group/{id}
HOWEVER I have different fields that are needed to be updated by users with different permissions, for instance: A group might have the structure
{
"id": 1,
"name": "some name",
"members": [
{
"user_id": 456,
"known_as": "Name 1",
"user": { /* some user object */},
"status": "accepted",
"role": "admin",
"shared": "something"
},
{
"user_id": 999227,
"known_as": "Name 1",
"user": { /* some user object */},
"status": "accepted",
"role": "basic",
"shared": "something"
},
{
"user_id": 9883,
"known_as": "Name 1",
"user": { /* some user object */},
"status": "requested",
"role": "basic",
"shared": "something"
}
],
"link": "https://some-link"
}
As an example I have the following 3 operations for the /group/{id}/members/{id} endpoint:
I want only the user to be able to update his own known_as field
I want only group admins to be able to update each member's role and status fields.
I want both the user and the admin to be able to update the shared field
My options are this:
Should I allow all updates to be done by POSTing to /group/{id}/members/{id} with a subset of the fields for a member and throw an unauthorized error if they try to update a field that they aren't allowed to update?
Or should I break each operation into say /group/{id}/members/{id}/role, /group/{id}/members/{id}/shared and /group/{id}/members/{id}/status? The problem with this is that I don't want to have to make lots of requests to update all the fields (I imagine that there will end up being quite a lot of them).
So just for clarification my question is: Is it considered proper REST to do my option 1 where I can post updates to an endpoint that may fail if you try to change a field that you aren't allowed to?
In my opinion, option 1 is much better than option 2.
As you said option 2 is a waste of bandwidth.
More importantly, with option 1 you can easily implement an atomic update (update "all-or-nothing"). It should either complete successfully or fail entirely. There should never be a partial update.
With option 2 it's very likely the update can be implemented to complete some request successfully and reject another request, even if the two requests are considered a single operation.
I would like to GET all drop down options for a custom field. For system fields, I use the following URI:
http://localhost:8080/rest/api/2/project/XXXX/components
(for components, versons, etc. Basically system fields), so I tried the following for a custom field
http://localhost:8080/rest/api/2/project/XXXX/customfield_10000
and got a 404 error. I'm not sure what I'm doing wrong as I've been googling for the past 19 hours. The best I search result I got was the following documentation: JIRA Developers Documentation
Please assist, I'm not sure What I'm missing
You can get that information either from the createmeta or editmeta REST resources.
Use editmeta if you want to retrieve the available options when editing a specific issue. E.g.
GET /rest/api/2/issue/TEST-123/editmeta
Use createmeta when you want to retrieve the options for a project in combination with an issue type. E.g.
GET /rest/api/2/issue/createmeta?projectKeys=MYPROJ&issuetypeNames=Bug&expand=projects.issuetypes.fields
The customfields with options will be returned like this:
"customfield_12345": {
"schema": {
"type": "string",
"custom": "com.atlassian.jira.plugin.system.customfieldtypes:select",
"customId": 12345
},
"name": "MySelectList",
"allowedValues": [
{
"self": "http://jira.url/rest/api/2/customFieldOption/14387",
"value": "Green",
"id": "14387"
},
{
"self": "http://jira.url/rest/api/2/customFieldOption/14384",
"value": "Blue",
"id": "14384"
}
]
}