Unable to grant secure file permissions to a pipeline via REST API - rest

I have an Azure DevOps pipeline that publishes a secure file to the pipeline library. What I would like to do is immediately grant that file permissions to a pipeline (so that I don't have to go in and manually do so). I have been following this documentation:
https://learn.microsoft.com/en-us/rest/api/azure/devops/approvalsandchecks/pipeline-permissions/update-pipeline-permisions-for-resources
My PATCH method is as follows:
curl --location --request PATCH 'https://dev.azure.com/{myOrganization}/{myProject}/_apis/pipelines/pipelinepermissions?api-version=7.0-preview.1' \
--header 'Authorization: Basic {myAuth} ' \
--header 'Content-Type: application/json' \
--data-raw '[
{
"resource": {
"type": "secureFile",
"id": "{mySecureFileId}"
},
"pipelines": [
{
"id": {myPipelineId},
"authorized": true
}
]
}
]'
For reference, the URL to the secure file is:
https://dev.azure.com/{myOrganization}/{myProject}/_library?itemType=SecureFiles&view=SecureFileView&secureFileId={mySecureFileId}&path={secureFileName}
and the URL to my pipeline is:
https://dev.azure.com/{myOrganization}/{myProject}/_build?definitionId={myPipelineId}&_a=summary
But my response is always:
Status: 200 OK
{
"count": 0,
"value": []
}
No permissions get set. The documentation does say that a 200 response is correct, but the count being 0 means that nothing was patched. I confirmed that the resource type of secureFile is correct when I change the secureFileId or pipelineId to ones that do not exist, I get an expected 404 response.
So as far as I can tell, my syntax and IDs are all correct, but I still have not been able to successfully grant the permissions.
Any ideas?

Instead of using: Pipeline Permissions - Update Pipeline Permisions For Resources, in your scenario, you should use: Pipeline Permissions - Update Pipeline Permisions For Resource
Pipeline Permissions - Update Pipeline Permisions For Resource is used to Authorizes/Unauthorizes a list of definitions for a given resource.
So modify your API as below, it should work:
PATCH https://dev.azure.com/{organization}/{project}/_apis/pipelines/pipelinepermissions/{resourceType}/{resourceId}?api-version=7.0-preview.1
Modify your script as below:
curl --location --request PATCH 'https://dev.azure.com/{organization}/{project}/_apis/pipelines/pipelinepermissions/{resourceType}/{resourceId}?api-version=7.0-preview.1' \
--header 'Authorization: Basic {myAuth} ' \
--header 'Content-Type: application/json' \
--data-raw '[
{
"pipelines": [
{
"id": {myPipelineId},
"authorized": true
}
]
}
]'

Related

SendGrid: "batch id not found"

I'm playing around with the v3 API and trying to demo the concept of scheduling emails and then cancelling them. Here is what I did:
Created a batch with POST https://api.sendgrid.com/v3/mail/batch and got batch a batch ID
Did a mail send with POST https://api.sendgrid.com/v3/mail/send and included that batch ID as the batch_id parameter and put in a future send_at time
Attempted to pass that batch ID into POST https://api.sendgrid.com/v3/user/scheduled_sends/:batch_id
However the latter call fails as 404 Not Found with "message": "batch id not found". In fact it would seem that however many batch IDs I create, attempting to update them always yields this not-found message. The result is, the scheduled send cannot be cancelled, and the email sends at the appointed time. I should add that attempting to GET /v3/mail/batch/{batch_id} returns an empty array [].
Am I doing something wrong here?? Is this a limitation of the free account perhaps?
EDIT: I'm going to add some raw details to show what I am doing. I am doing these in Postman but I will export in cURL syntax to demonstrate.
First I create a batch:
curl --location --request POST 'https://api.sendgrid.com/v3/mail/batch' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <token redacted>' \
--data-raw ''
Response: {"batch_id":"OWU0NzgxYzUtMjkzZS0xMWVkLTg5NDAtYWUyMDAwNjVjZGU0LTZiODk2MDliZA"}
So now the next thing I want to try is to verify that batch ID:
curl --location --request GET 'https://api.sendgrid.com/v3/user/scheduled_sends/OWU0NzgxYzUtMjkzZS0xMWVkLTg5NDAtYWUyMDAwNjVjZGU0LTZiODk2MDliZA' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <token redacted>'
The response is, oddly, a 200 OK with just [] which doesn't seem right does it? I created a batch and it has an ID, so why can't I verify its existence?
Documentation here states: https://docs.sendgrid.com/api-reference/cancel-scheduled-sends/validate-batch-id
When you pass a valid batch_id to this endpoint, it will return a 200
status code and the batch ID itself.
If you pass an invalid batch_id to the endpoint, you will receive a
400 level status code and an error message.
A batch_id does not need to be assigned to a scheduled send to be
considered valid. A successful response means only that the batch_id
has been created, but it does not indicate that it has been associated
with a send.
Interestingly if I put any arbitrary string in that URL instead of a batch ID, I also get a 200 OK with empty array. I cannot even reproduce what the document is saying about receiving a 400 error for an invalid ID.
However if I take it on faith that the batch WAS created, I would go ahead and try to send an email with it:
curl --location --request POST 'https://api.sendgrid.com/v3/mail/send' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token redacted>' \
--data-raw '{
"batch_id": "OWU0NzgxYzUtMjkzZS0xMWVkLTg5NDAtYWUyMDAwNjVjZGU0LTZiODk2MDliZA",
"send_at": 1661969713,
"personalizations": [{
"to": [{
"email": "thatemail#mycompany.com",
"name": "John Doe"
}
]
}],
"from": {
"email": "myemail#mycompany.com",
"name": "Jane Doe"
},
"reply_to": {
"email": "customer_service#example.com",
"name": "Example Customer Service Team"
},
"subject": "Example Email 6",
"content": [{
"type": "text/html",
"value": "<p>Test email!</p><p>%open-track%</p>"
}
],
"custom_args":{
"sf-id": "some-arbitrary-id6",
"sf-org-id": "some-arbitrary-org-id"
},
"mail_settings": {
"sandbox_mode": {
"enable": false
}
},
"tracking_settings": {
"click_tracking": {
"enable": true,
"enable_text": false
},
"open_tracking": {
"enable": true,
"substitution_tag": "%open-track%"
},
"subscription_tracking": {
"enable": false
}
}
}
'
At the time of writing that timestamp is for 3h from now, resolving at 2:15PM August 31st Eastern Time. I send that call and get 202 Accepted.
Then, finally, I attempt to pause the batch.
curl --location --request PATCH 'https://api.sendgrid.com/v3/user/scheduled_sends/OWU0NzgxYzUtMjkzZS0xMWVkLTg5NDAtYWUyMDAwNjVjZGU0LTZiODk2MDliZA' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token redacted>' \
--data-raw '{"status": "pause"}'
My response is a 404 NOT FOUND with:
{
"errors": [
{
"field": null,
"message": "batch id not found"
}
]
}
So... what is going on here???
So a few things:
It turns out I was missing a step here. The first time I want to put in a pause or cancel on a batch, I actually need to POST /v3/user/scheduled_sends/ with batch_id in the request body. I was trying PATCH. Strange behaviour here as the batch ID already exists, but OK.
After my first successful test of this, the entire behaviour of the GET /v3/mail/batch/{batch_id} API changed for me. I am no longer able to reproduce getting back an empty array. Every response is either a success with the batch ID or a fail.
I don't know why these behaviours changed, but they did. There may be some quirk in which fresh accounts that have never paused/cancelled a batch simply do not have a functional "validate batch" call. Now that I have done a successful pause for the first time, the behaviour of GET /v3/mail/batch/{batch_id} finally matches the documentation.

how to regenerate pagerduty integration key programmatically

I have integrated Jenkins CI with pagerduty. Once I do that, I can see intergration key generated.
That will be used in jenkins to send the events to pagerduty.
The requirement is to rotate the keys after some time. I want to automate this.
Is there any api to regenerate the intergration key and return the key in response to be stored in jenkins?
I think the simplest solution here is to use the REST API -- it isn't possible to regenerate the integration key directly, but you can delete the integration and create a new one programmatically.
First fetch the service details:
curl --location --request GET 'https://api.pagerduty.com/services/<service_id>' \
--header 'Accept: application/vnd.pagerduty+json;version=2' \
--header 'Authorization: Bearer <bearer_token>'
This will include all of the integrations on the service -- make note of the integration_id and the vendor_id.
The delete endpoint isn't documented but it does seem to exist:
curl --location --request DELETE 'https://api.pagerduty.com/services/<service_id>/integrations/<integration_id>' \
--header 'Accept: application/vnd.pagerduty+json;version=2' \
--header 'Authorization: Bearer <bearer_token>'
And finally you can create the new integration, using the vendor_id from the GET request:
curl --request POST \
--url https://api.pagerduty.com/services/id/integrations \
--header 'Accept: application/vnd.pagerduty+json;version=2' \
--header 'Authorization: Bearer <bearer_token>' \
--header 'Content-Type: application/json' \
--data '{
"integration": {
"type": "generic_email_inbound_integration",
"name": "Email",
"service": {
"id": "<service_id>",
"type": "service_reference"
},
"integration_email": "my-email-based-integration#subdomain.pagerduty.com",
"vendor": {
"type": "vendor_reference",
"id": "<vendor_id>"
}
}
On doing inspect element to UI button
Its executing POST API:
https://xxxxxxx.pagerduty.com/api/v1/services/XXXXXXX/integrations/XXXXXXX/regenerate_key

Why does creating token result in "parent token lookup failed"

I have an issue with creating tokens for hashicorp-vault using salt.
Create token:
$ curl --header "X-Vault-Token: f3821c23-4558-72db-8739-bbf7ac4b90d1" \
--request POST \
--data #create_token.json \
http://127.0.0.1:8200/v1/auth/token/create
{"request_id":"72ba8117-fcb8-506d-f1c4-fe0e5e0f5cbf","lease_id":"","renewable":false,"lease_duration":0,"data":null,"wrap_info":null,"warnings":["Policy \"saltstack/minion/myhost\" does not exist"],"auth":{"client_token":"96bfd0f2-a10a-d966-2d46-3f803fb1d995","accessor":"8a0a296f-d19a-e01c-4782-0fbab06a6ebe","policies":["default","saltstack/minion/admin.p13","saltstack/minions"],"metadata":null,"lease_duration":2764800,"renewable":true,"entity_id":""}}
Create a child token using client_token of the first operation.
$ curl --header "X-Vault-Token: 96bfd0f2-a10a-d966-2d46-3f803fb1d995" \
--request POST \
--data #test.json \
http://127.0.0.1:8200/v1/auth/token/create
{"errors":["parent token lookup failed"]}
Used payloads:
File create_token.json
{"policies": ["saltstack/minion/myhost", "saltstack/minions"], "num_uses":1}
File test.json
{"num_uses": 0, "policies": ["default", "myapp"], "ttl": "1h", "no_parent": true, "renewable": true, "metadata": {"user": "root"}}
The orphan tokens can only be created:
Via the auth/token/create-orphan endpoint
By having sudo capability or root policy when accessing auth/token/create and setting the orphan parameter to true
Which implies that your initial token doesn't have root policy associated with it. as you can see below in your policies list,
"policies":["default","saltstack/minion/admin.p13","saltstack/minions"],"metadata":null,"lease_duration":2764800,"renewable":true,"entity_id":""}}
Beside,
If you are using salt, then your Master token must have privileges to create new tokens in minions, which you can then create using vault.write_secret

JSON_PARSER_ERROR on PATCH when updating a custom object

I am attempting to update a custom object using the Salesforce REST API as described here, but I consistently receive this 400 response
[
{
"message": "The HTTP entity body is required, but this request has no entity body.",
"errorCode": "JSON_PARSER_ERROR"
}
]
I have tried appending ?_HttpMethod=PATCH to the url and switching to a POSTcall, but while that yields 200 OK, it doesn't actually update the object. The object is "updateable" and I do have permission to edit it. Editing it directly in Salesforce works without issues.
Here is my (cleaned) request, as exported from Insomnia [Version 5.14.9 (5.14.9.1895)].
curl --request PATCH \
--url https://myInstance.salesforce.com/services/data/v20.0/sobjects/CUSTOMOBJECT/CUSTOMOBJECTID \
--header 'authorization: Bearer token' \
--header 'content-type: application/json' \
--data '{
"Additional_Information__c": "Test additional information"
}'
Any ideas on how I can resolve this?
According to the Salesforce documentation for sending HTTP requests with cURL, either a JSON data file needs to be sent or a ".json" extension needs to be appended to the URI.
curl --request PATCH \
--url https://myInstance.salesforce.com/services/data/v20.0/sobjects/CUSTOMOBJECT/CUSTOMOBJECTID.json \
--header 'authorization: Bearer token' \
--header 'content-type: application/json' \
--data '{
"Additional_Information__c": "Test additional information"
}'

get build status through github api

The GitHub API provides a lot of functionality, but is there a way to retrieve the build status for a commit? The GitHub UI provides information from the CI system we have configured, but I can't see this information exposed through the API?
You can access the status for a particular ref
GET https://api.github.com/repos/:owner/:repo/commits/:ref/statuses
For the value of :ref, you can use a SHA, a branch name, or a tag name.
It doesn't provide status directly, but offers you to create a status
That means the CI can have a final build step which publishes the status to GitHub repo that way.
POST /repos/:owner/:repo/statuses/:sha
For example:
{
"state": "success",
"target_url": "https://example.com/build/status",
"description": "The build succeeded!",
"context": "continuous-integration/jenkins"
}
(and that, for a given SHA1)
See for instance "Github Commit Status API with Bamboo from Atlassian", where:
${bamboo.buildResultsUrl} is the GitHub commit SHA1:
<xxx> is a placeholder value, which can be replaced by a value, or a variable ${var} as shown here.
Add those to your plan as Script.
complete.sh:
# specs and cukes results are stored in JUnit format under test-reports
if (grep 'failures="[^0]"' test-reports/* || \
grep 'errors="[^0]"' test-reports/*); then
curl -H "Authorization: token <MY_TOKEN>" --request POST \
--data '{"state": "failure", "description": "Failed!", \
"target_url": "${bamboo.buildResultsUrl}"}' \
https://api.github.com/repos/<USER>/<REPO>/statuses/${bamboo.repository.revision.number} > /dev/null
else
curl -H "Authorization: token <MY_TOKEN>" --request POST \
--data '{"state": "success", "description": "Success!", \
"target_url": "${bamboo.buildResultsUrl}"}' \
https://api.github.com/repos/<USER>/<REPO>/statuses \
/${bamboo.repository.revision.number} > /dev/null
fi
pending.sh:
curl -H "Authorization: token <MY_TOKEN>" --request POST \
--data '{"state": "pending", "description": "Build is running", \
"target_url": "${bamboo.buildResultsUrl}"}' \
https://api.github.com/repos/<USER>/<REPO>/statuses/${bamboo.repository.revision.number} > /dev/null