Implement Synthetic API Request_body on Terraform (Datadog) - terraform

I'm trying to develop a Synthetic API test on Terraform for Datadog.
The API in question need a Request_Body parameter to properly make the test.
I've search in many sites on how to implement such Request_body parameter in Terraform but so far, I couldn't see any example of it.
Can someone help me with this?
resource "datadog_synthetics_test" "TEST_Status"
{
type = "api"
subtype = "http"
request_definition {
method = "POST"
url = "(...)"
}
request_headers = {
"origin" = "(...)"
"content-length" = "1340"
"accept-language" = "en-US,en;q=0.9,pt;q=0.8"
(............)
}
Thanks in advance

You missed body, it's mandatory for post requests
request_definition {
method = "POST"
url = "(...)"
body = "body content ..."
}

Related

Query regarding parameters for alerting

I am trying to create a synthetic test in Datadog using terraform. There is an option to alert when synthetic test fails for a specific duration on the interface while creating a synthetic test.
This will alert only when the test fails for the duration.
I tried to find a similar parameter in the resource on the terraform documentation but can't find any
https://registry.terraform.io/providers/DataDog/datadog/latest/docs/resources/synthetics_test
Can anyone help me to find any equivalent parameter to alert when the test fails for a specific duration using terraform resource?
There is an attribute min_failure_duration which can be added in the resource. The value is in seconds so if you want to create a synthetic test that alerts only when the duration of failure is >=3 min, you can add this attribute as min_failure_duration = 180
resource "datadog_synthetics_test" "test_api" {
type = "api"
subtype = "http"
request_definition {
method = "GET"
url = "https://www.example.org"
}
request_headers = {
Content-Type = "application/json"
Authentication = "Token: 1234566789"
}
assertion {
type = "statusCode"
operator = "is"
target = "200"
}
locations = ["aws:eu-central-1"]
options_list {
tick_every = 900
--> min_failure_duration = 180
retry {
count = 2
interval = 300
}
monitor_options {
renotify_interval = 100
}
}
name = "An API test on example.org"
message = "Notify #pagerduty"
tags = ["foo:bar", "foo", "env:test"]
status = "live"
}

Httpbuilder put examples for sending multiple query params groovy

I am using Httpbuilder 0.7.1 and groovy 1.8 to invoke the rest call.
I need to send the mutiple values for the same query parameter but it is not working.
I need to send values as below
https:///?action=test&group=grp1&group=grp2
I have tried with the code below and it is working as expected.
Map query = [:]
Map headerMap = [:]
headerMap["Accept"] = 'application/json'
headerMap["Authorization"] = authtoken
def groupsListArray=[]
if (group.contains(",")) {
def groupsList = group.split(",");
for ( singlegroup in groupsList) {
groupsListArray.add(singlegroup.toString())
}
query.put("group",groupListArray)
}
else{
query.put("group",group)
}
def http = new HTTPBuilder(baseUrl)
http.request(method) { req ->
uri.path = path
uri.query = query
headerMap.each { key, value ->
headers."${key}" = "${value}" }
}
Is there any other way, we can send multiple values for the same query parameter with httpbuilder?
Okie, the issue has been identified with the REST service and there is no issue with this code.Thanks for the help

CDON API RESTful Api GET request

I'm currently working on fetching customer data from cdon, it's an e-commerce platform. They have their API documentation here:
CDON Api Docu
First let me show you my code:
myToken = '<token here>'
myUrl = 'https://admin.marketplace.cdon.com/api/reports/d8578ef8-723d-46cb-bb08-af8c9b5cca4c'
head = {'Authorization': 'token {}'.format(myToken),
'Status':'Online',
'format':'json'}
filters = '?filter={"Status":["Online"],"format": ["json"] }}'
response = requests.get(myUrl + filters, headers=head)
report = response.json()
print(report.products)
This is returning only the parameters. like for example at at this JSON: CDON Github
Status has a value Online this online is a group of itemsthat I only want to get.
What I'm trying to get is a response like this:
{
"Products": [
{
"SKU": "322352",
"Title": "Fabric Cover",
"GTIN": "532523626",
"ManufacturerArticleNumber": "",
"StatusCDON": "Online",
"ExposeStatusCDON": "Buyable",
"InStock": 0,
"InStockCDON": 0,
"CurrentPriceSE": null,
"OrdinaryPriceSE": null,
"CurrentPriceCDONSE": 299.0000,
"OrdinaryPriceCDONSE": null,
"CurrentPriceDK": null,
"OrdinaryPriceDK": null,
"CurrentPriceCDONDK": null,
"OrdinaryPriceCDONDK": null,
"CurrentPriceNO": null,
"OrdinaryPriceNO": null,
"CurrentPriceCDONNO": null,
"OrdinaryPriceCDONNO": null,
"CurrentPriceFI": null,
"OrdinaryPriceFI": null,
"CurrentPriceCDONFI": null,
"OrdinaryPriceCDONFI": null
},
Which means the full list of the items that are Online
How should I put this... among all the API's I tried this one is very confusing, is this even RestFul? If I can achieve the python equivalent of this C# sample code:
public string Post(Guid repordId, string path)
{
var filter = new JavaScriptSerializer().Serialize(new
{
States = new[] { "0" } // Pending state
});
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair("ReportId", repordId.ToString()),
new KeyValuePair("format", "json"),
new KeyValuePair("filter", filter)
});
var httpClient = new HttpClient() { BaseAddress = new Uri("https://admin.marketplace.cdon.com/") };
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("api", ApiKey);
var response = httpClient.PostAsync(path, content).Result;
response.EnsureSuccessStatusCode();
return response.Content.ReadAsStringAsync().Result;
}
I may be able to undestand how this API works, the response that I got was taken manually from their report function in JSON format.
Image
I made many attempts and at that code ( my code ) I stopped, being on this for 4 hours made me give up and ask. Trust that I have searched as many references as I could. It's really confusing.
How do I get the response that I want? Filtering via url? or via header? is this even restful? Help T_T
The documentation states in the first line, emphasis mine:
In order to generate a report you perform a POST call to the reports API with the parameters you wish to use for the report.
Your Python code does not make a POST request, you are trying a GET request. The documentation goes on
[...] to filter on Swedish orders you set the CountryCodes
attribute to “Sweden” and to get returned and cancelled orders you set
the States attribute to 2 and 3. So in the end the filter would look
like this:
{
"CountryCodes": [ "Sweden" ],
"States": ["2", "3"]
}
So you need to prepare a filter object (a dictionary in Python) with the filters you want. Luckily the Python syntax for dictionaries is equivalent (Python is flexible and also allows single-quoted strings):
filter = {
'CountryCodes': [ 'Sweden' ],
'States': [ '0' ]
}
The documentation goes on
You then post the parameters as form data (content-type:
application/x-www-form-urlencoded) so the request body would look like
this:
ReportId=d4ea173d-bfbc-48f5-b121-60f1a5d35a34&format=json&filter={"CountryCodes":["Sweden"],"States":["2","3"]}
application/x-www-form-urlencoded is the default for HTTP post, the requests module knows that and does this for you automatically. All you need to do is to prepare a data dict which will contain the data you want to post.
data = {
'ReportId': 'd4ea173d-bfbc-48f5-b121-60f1a5d35a34',
'format': 'json'
'filter': json.dumps(filter)
}
The filter parameter is supposed to be in JSON format. You must encode that yourself via json.dumps().
import json
head = { ... as above }
filter = { ... as above }
data = { ... as above }
response = requests.post(url, data, header=head)
I'll leave figuring out setting the Authorization header properly as an exercise for you. Partly because it isn't hard, partly because I have no intention of creating an API key with this website just for testing this and partly because it's entirely possible that your current header already works.

Decoding JSON string to terraform map

I'm using the HTTP data source to retrieve data from an internal service. The service returns JSON data.
I can't interpolate the returned JSON data and look up data in it.
For example:
module A
data "http" "json_data" {
url = "http://myservice/jsondata"
# Optional request headers
request_headers {
"Accept" = "application/json"
}
}
output "json_data_key" {
value = "${lookup(data.http.json_data.body, "mykey")}"
}
main.tf
provider "aws" {
region = "${var.region}"
version = "~> 0.1"
}
module "moduleA" {
source = "../../../terraform-modules/moduleA"
}
resource "aws_instance" "example" {
ami = "ami-2757f631"
instance_type = "${module.moduleA.json_data_key}"
}
The lookup function will fail to extract the key within the JSON data.
Is there any way to decode the JSON data into a terraform map ?
variable "json" {
default = "{\"foo\": \"bar\"}"
}
data "external" "json" {
program = ["echo", "${var.json}"]
}
output "map" {
value = "${data.external.json.result}"
}
Not directly related to map convertion, but here's an additional sample with jsondecode if you got a multi-value secret (=JSON) in AWS SecretsManager & you want to use separate values from it in another service as I've struggled with this.
Retrieving the secret:
data "aws_secretsmanager_secret" "oauth_client" {
name = "oauth-client"
}
data "aws_secretsmanager_secret_version" "oauth_client" {
secret_id = data.aws_secretsmanager_secret.oauth_client.id
}
Using it at Lambda, as an example:
resource "aws_lambda_function" "lambda" {
[...]
environment {
variables = {
OAUTH_CLIENT_ID = jsondecode(data.aws_secretsmanager_secret_version.oauth_client.secret_string)["client_id"]
OAUTH_CLIENT_SECRET = jsondecode(data.aws_secretsmanager_secret_version.oauth_client.secret_string)["client_secret"]
}
}
}
Ok, so it seems to be that the way to do the is by using the external data, as it return a map from a json response.
https://www.terraform.io/docs/providers/external/data_source.html
terraform version v0.10.6
Since 0.12 version of the Terraform you can use jsondecode function to decode json into a Terraform map. More details on: https://www.terraform.io/docs/configuration/functions/jsondecode.html
example from the page above:
> jsondecode("{\"hello\": \"world\"}")
{
"hello" = "world"
}
> jsondecode("true")
true

Gmail API - How to Request Only one Name/Value Pair from Email Payload Headers?

How can we capture only the email address in an api response for the gmail API. The
fields parameter is set to payload/headers, which returns way more data than we need in the response.
All we need is the value from one name/value pair in the JSON response; for example
The full response as we have it now looks something like this
{
"payload": {
"headers": [
{
"name": "Delivered-To",
"value": "xxxxxxx"
{
"name": "Received",
"value": "xxxxxxxx"
},
{
"name": "Received-SPF",
"value": "----"
},......
{
"name": "To",
"value": "xxxxxxx"
}, ...... E.T.C........E.T.C ......
/*All we want is one name/value pair to be returned e.g. */
{
"payload": {
"headers": [
{
"name": "X-Failed-Recipients",
"value": "............."
}
]
}
A better question might be is there a better way to capture bounced/returned mail than this via the gmail API?
Also, is it possible to request an XML response instead of JSON. How can that be done for the gmail API?
Thanks !!
You can do messages.get(format=METADATA, metadataIncludeHeaders=["To", "From", "Subject"]) for example, now to just request the specific headers you care about . Note this only works with the metadata format (it won't include the body also, if you want all the body you get the full email. Based on the list of headers, shouldn't be too hard to turn that into a map/dict of key => [list, of, values].
As to your second question, yes you can definitely request response in any format you want. That's a standard Google API question though. I can't find a good reference (surely some searching will) but typically you can set an "alt=xml" or "alt=" query parameter to get response in that format. Not sure how this is exposed in any particular client library.
First you need to get your message payload and then you want to use the getall method to return a list of headers and then you can use the getitem to pull any specific header you want from that list.
I converted the String into a String and took it as a JSON Array and iterated through it to take the JSON Object that I required.
private static DirtyMail getHeaderParts(DirtyMail mail, List<MessagePartHeader> headers)
{
try {
//Convert the header into JSON Array for easy processing of data.
JSONArray headerArray = new JSONArray(headers.toString());
for(int n = 0; n < headerArray.length() ; n++) {
JSONObject jsonObject = headerArray.getJSONObject(n);
//Pull date
if(jsonObject.get(Constants.DATE)!=null) {
mail.setDate(jsonObject.getString(Constants.DATE));
}
//Pull Subject
//Pull reply-to address
//Pull delivered-from address
//Pull delivered-to address
Log.d(TAG, "JSON Object : "+ jsonObject);
}
//Log.d(TAG,"header String: "+headers.toString());
} catch (Exception e) {
e.printStackTrace();
}
return mail;
}
I kept these values in the Constant class :
// Data pulled from inside the header
public static final String DATE = "Date";
public static final String SUBJECT = "Subject";
public static final String REPLY_TO = "Reply-To";
public static final String DELIVERED_TO = "Delivered-To";
public static final String FROM = "From";
I don't know if this is the best fix for this, but this works and gives the data as I require.

Resources