Return Hosted Agent usage via API? - azure

I want to create some reporting around pipelines that use MS hosted public agents to run jobs.
This info is available via the UI (Org Settings > Agent Pools > Azure Pipelines) - but not via the REST API it would seem.
I can return all Agent Pools:
GET https://dev.azure.com/{organization}/_apis/distributedtask/pools?api-version=7.1-preview.1
...and then filter on the "isHosted" property - but the pool info has no run history.
Alternatively I can loop through all projects in the Org (lots!), loop through all pipelines, then finally loop through all runs for each pipeline - but the run doesn't have an agent property either.
I tried looking at Service Hooks to trigger a webhook when a build is run to see if I could pull the agent / pool detail from the payload - buts its not in there either.
Any other ideas welcome.

When encountered those situation, you always have two ways.
1, First of all, if UI can show what you want, you can handle the data via python crawler.
#python crawler get the content of the page
import requests
url = "https://dev.azure.com/<Organization Name>/_settings/agentpools?poolId=9&view=jobs"
payload={}
headers = {
'Authorization': 'Basic <Personal Access Token>',
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
#save the content to a file
with open('jobs.html', 'w', encoding='utf-8') as f:
f.write(response.text)
After saving the data, use the regular expression to filter the data you want.
(This method is just a suggestion for common handling.)
2, Or you can use this REST API to query the public agents run history of your current situation:
https://dev.azure.com/<Organization Name>/_apis/distributedtask/pools/<Pool ID>/jobrequests
Public or private can be distinguished by ParallelismTag:

Related

How do I change my Slack bot icon in python?

I'm very (very) novice at playing with the Slack api - so be gentle and use short words. So far I have managed to set up a simple system that can post to our Slack channel. All well and good, but the icon associated with the posts is the default. How do I go about setting a different icon or even one I create myself?
Here is the basic code (snagged from a tutorial listed on teh Slack api dev site):
import requests
import json
url = 'https://slack.com/api/chat.postMessage'
token = 'xoxb-00000000000etc'
headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer {0}'.format(token)}
def send_message(message_text):
message = {'channel': '#channel_name', 'text': message_text}
requests.post(url, headers=headers, data=json.dumps(message))
send_message('beep boop - this is the OMS bot calling')
Many thanks...
To set the icon image for your message you can simple provide the property icon_url with a URL to an image.
Example:
message = {'channel': '#channel_name', 'text': message_text, 'icon_url': 'https://img.icons8.com/emoji/96/000000/penguin--v2.png'}
You can see all available properties on the official documentation page for the API method chat.postMessage.
Since you said you very a beginner allow me to make two additional suggestions.
1 - The offical Slack library
There is an official Slack library for Python which makes thinks much easier, e.g. you don't need to deal with the requests library and HTTP headers. You find it here: https://github.com/slackapi/python-slackclient
2 - Slack token in environment variables
For security reasons it is good practice to put your slack token in an environment variable. That way you also can check in your code into github etc.
Updated example
Here is your example with the two suggested improvements:
import slack
import os
client = slack.WebClient(token=os.environ['SLACK_TOKEN'])
response = client.chat_postMessage(
channel='general',
text='beep boop - this is the OMS bot calling',
icon_url='https://img.icons8.com/emoji/96/000000/penguin--v2.png'
)
When passing icon_url or icon_emoji to a bot, remember that the scope chat:write.customize is required. Otherwise it will have no effect.

Azure Build Pipeline - Pause and Enable DefinitionQueueStatus change REST API

We have many dozens of build pipelines and we want to pause and resume (re-enable) build pipelines from a simple webapp interface as we are making config changes frequently. Here is the MS doc explaining this API:
https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds/update%20build?view=azure-devops-rest-5.0#definitionqueuestatus
From this documentation, it appears I need to hit the REST API and change/toggle the DefinitionQueueStatus -- however, this documentation only shows a sample for a build specific operation, whereas I want to pause then re-enable the entire build pipeline. What is the proper way to make this call?
I'm using fetch - and I've tried many dozen formats in the call - the 'ourorg' and 'ourproject' are correct (we use this call structure for many other calls), but all fails for this call below. I grabbed the 'definitionID' from the URL I can visibly see when in the Azure devops portal on the specific build pipeline page, and I'm using it for the {buildID} as I don't know what else to put there. Any guidance to help here is appreciated - I don't need to use fetch btw - any working sample will help here:
fetch(https://dev.azure.com/our_org/our_projectname/_apis/build/builds/definitionId=1593?retry=true&api-version=5.0 {
method: 'PATCH ',
credentials: 'same-origin',
body: 'DefinitionQueueStatus: "Enabled"'
}).then(function(response) {
console.log(response);
})
It seems that the body is incorrect in your post. Here is sample about how to use POSTMAN to access Azure DevOps Services REST APIs.
Generate the PAT, and then record the token, it is important to use to authorization, please see this document.
Create a new request in POSTMAN, it is recommended to put the request in a collection for Azure DevOps Services REST API;
Select the authorization as Basic Auth, you can input the username as any value, and the password as the token which is generated in step1.
Basic Auth
Set the REST API which you want to use,and select the request method type(GET,POST,FETCH ....), here you use https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=5.0.
In the Body tab, you can set the request body as raw in json format, and input the value as following:
{
"buildNumber":"#20190607.2",
"buildNumberRevision":1,
"definition":
{
"id":1,
"createdDate":null,
"queueStatus":"paused"
}
}
Everthing is ready now, you can send the request, if sccuess, you will get the response from the REST API.
In your post, the body content is incorrect, the Request Body should meet the format in the REST API document. The DefinitionQueueStatus is a type in definitions. In addition, if you send the request with parameter retry, you will get the message The request body must be empty when the retry parameter is specified..

How to receive/access headers of the POST request and 'User Properties' from Data Factory task in Azure Function app

I'm still new to Azure, so please bear with me if this is a newbie question.
I created a task in Azure Data Factory that will invoke a Http-triggered Python function (Consumption plan). The settings and user properties of that task is as shown below:
and here
The function itself is as shown below:
Q1: I'd like to know how to read/access the headers of the POST request in the Python function ('run.py' in the screenshot above). For now, I could only access the body of the HTTP request by using os.environ['req'].
Q2: I'd also like to know if it's possible to access 'User Properties' in the 'run.py' assuming that I run the task in the Data Factory (the first and second screenshot). If so, how would I do that.
The existing resources (e.g., 1 and 2) that I could find online don't tell me yet. Any advice/tip would be greatly appreciated. Thank you in advance!
I finally figured it out and am sharing what I found below so that it helps everyone out there wondering the same thing as i did.
This is the code I wrote in Python Function App to access the body and the request headers.
import os
import json
# This is how I'm currently reading the **body of the POST request**
postreqdata = json.loads(open(os.environ['req']).read())
# This is how we should read **a header of the POST request**;
# here 'excelSourcePath' is one of the header names.
postreqdata['header1'] = os.environ['REQ_HEADERS_EXCELSOURCEPATH']
# 'User Properties' is just for monitoring purpose
# https://social.msdn.microsoft.com/Forums/en-US/8692cd00-307b-4204-a547-bed2030cb762/adfv2-user-property-setting?forum=AzureDataFactory
response = open(os.environ['res'], 'w')
response.write(json.dumps({'This is what I see from POST request now':postreqdata}))
response.close()
Hope this is helpful.

Google Analytics API service object - no management attribute

I am trying to set up an application that uses the Google Analytics API. I have all the authorization steps working correctly and can pull all the data as expected. However, at the moment, it is working because I have hardcoded my own view ID into the queries to the API. E.g:
response = analytics.reports().batchGet(
body={
"reportRequests":
[
{
"viewId": "ga:12345678",
...
From what I understand, what I need to do is before I start querying the data, is use the service object to first get a view Id (or list of View Ids), then use that in the data queries. I have been attempting to do just that and have been failing miserably. Basically, I have the following (just to get the first step of a list of accounts):
credentials = client.OAuth2Credentials.from_json(session['credentials'])
http = credentials.authorize(httplib2.Http())
analytics = build('analytics', 'v4', http=http) #create the service object
data = analytics.management().accounts().list().execute()
The error I am getting is 'Resource' object has no attribute 'management'. What am I missing here??
Ok, so for those who come across this question, the issue seemed to be that, as of the time of writing, version 4 of the API does not have the management features. What I/we did instead was build a second service to get the account details using version 3:
service = build('analytics', 'v3', http=http)
accounts = service.management().accounts().list().execute()
That seemed to do the trick, although there was some additional fiddling required in order to get the view ID(s). However, once you have the object, it is just a matter of manipulating the object as needed.

Creating new task through WebHook with Asana API

I am working with a form system very similar to WUFOO that allows me to send data to an external website using WebHooks.
I have been able to connect my form to my ASANA system through Zapier but I cannot seem to get the API system to operate correctly. Can someone please advise or assist me on what I am doing incorrectly here?
In the screenshot note the following:
- Web URL functions for any web URL (https or http)
- HTTP method has POST, PUT, or GET options
- Data format allows me to input virtually anything so I can match up form fields with any necessary names for ASANA.
I simply cannot get the system to connect to ASANA. Please help me.
Screen shot of WebHook Options
I don't have access to your exact form builder but assuming it does what it says it is doing you can try the following. I'll use creating a task as an example.
Create a personal access token in Asana. To do this log in to Asana, click the icon in the top right corner and open "My profile settings". Go to the apps tab and create a personal access token. You will only ever see this token once so create a new one if you lose it. Also retrieve your workspace id, you can get it by opening app.asana.com/api/1.0/workspaces while logged in.
Now back to your form. For the website url place the specific endpoint you want to hit at Asana. For example, lets create a new task:
https://app.asana.com/api/1.0/tasks
Under the HTTP Method you want to select POST
Under the HTTP Headers you want to specify something like (replace 0/1234abcd with your access token):
{
"Authorization": "Bearer 0/1234abcd",
"Content-Type": "application/json"
}
You can use Send Raw Data and specify something like the following in the raw data section (replace 1234 with your workspace id):
{
"data": {
"workspace": 1234,
"name": "The name of the task"
}
}
You can of course add other fields- please see the API reference for more information:
https://asana.com/developers/api-reference/tasks
Let me know if that works for you.

Resources