I would like to get the instance metadata (like AZ) for the current EC2, using AWS SDK.
I was able to find an alternative solution, but it is not using the SDK just a file_get_contents
How is it possible with the SDK?
The solution proposed by JasonQ-AWS is useful to get information about all instances and applications in your account. However, it does not tell you what information describes the instance that is really executed by the current process.
For that you have to use IMDSv2 which requires two CURL commands, the first one to get a TOKEN and the second one to get the actual metadata of the current instance.
In PHP the code can therefore be :
$ch = curl_init();
// get a valid TOKEN
$headers = array (
'X-aws-ec2-metadata-token-ttl-seconds: 10' );
$url = "http://169.254.169.254/latest/api/token";
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "PUT" );
curl_setopt( $ch, CURLOPT_URL, $url );
$token = curl_exec( $ch );
echo "<p> TOKEN :" . $token;
// then get metadata of the current instance
$headers = array (
'X-aws-ec2-metadata-token: '.$token );
$url = "http://169.254.169.254/latest/dynamic/instance-identity/document";
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "GET" );
$result = curl_exec( $ch );
echo "<p> RESULT :" . $result;
All you have to do is to extract the desired information. You can also ask for a unique information, such as the instance id with a more specific url like :
$url = "http://169.254.169.254/latest/meta-data/instance-id";
By current EC2 instance, are you referring to PHP code running on an EC2, and you would like to inject that metadata into some variables for use?
Or do you mean you have an object created with the PHP SDK such as with something like:
$ec2Client = new Aws\Ec2\Ec2Client([
'region' => 'us-east-1',
'version' => 'latest'
]);
If you mean the second way, you can access that data through describeInstances like this:
$result = $ec2Client->describeInstances();
echo "Instances: \n";
foreach ($result['Reservations'] as $reservation) {
foreach ($reservation['Instances'] as $instance) {
echo "InstanceId: {$instance['InstanceId']} - {$instance['State']['Name']} \n";
echo "Availability Zone: {$instance['Placement']['AvailabilityZone']} \n";
}
echo "\n";
}
You can also filter by adding parameters to the method call such as by type or instanceId.
If you're just running PHP code on the EC2 instance and you want that info, you can check out this page for some options: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html
I don't think this is possible at all. IMDSv2 info like AZ, instance-id, instance-type, etc is readable via https://169.254.169.254 and if you look into the source code for the SDK, it only pulls temporary credentials via IMDSv2 (https://github.com/aws/aws-sdk-php/search?q=169.254)
and does not allow arbitrary IMDSv2 queries.
Unless I'm missing something, you need to pull this data yourself or use some 3rd-party library which does that for you in PHP.
Related
Good evening good people. I have run across an issue that I am trying to resolve. Here is the context:
In an email template (using the email service provider Mad Mimi) I have a placeholder {name}
In my implementation of calling their API to send a transactional email, I am posting data using a cURL request. This data includes my api key and username, so I can't give that part of the code but here is a link to the documentation that I am using to try to get this done. (https://madmimi.com/developer/mailer/methods)
Here is the sample from the link above:
promotion_name=Welcome to Acme Widgets
recipient=Dave Hoover <dave#example.com>
body=--- \nname: Some YAML data\n
My PHP Code is this: (there are 2 other variables before these)
$myvars .= '&recipient='.$email;
$myvars .= '&promotion_name=Welcome';
$myvars .= '&body= name: Some YAML data';
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_POST, 1);
curl_setopt( $ch, CURLOPT_POSTFIELDS, $myvars);
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
return (curl_exec( $ch ));
The result that I get from the send is:
Email Result:Your body parameter was unable to be parsed, due to: (): mapping values are not allowed in this context at line 1 column 9. Please ensure the body parameter is valid YAML: --- name: Some YAML data...
Can anyone help out?
Thanks!!
Edit: I changed my code to be like this:
$url = 'https://api.madmimi.com/mailer';
$myvars = [
"username" => "xxxxxxxxxx",
"api_key" => "xxxxxxxxxx",
"recipient" => "xxxxx#gmail.com",
"promotion_name" => "Welcome",
"body" => "--- \n firstname:John\n"
];
error_log('Mailer API Variables: ' . $myvars);
//TODO: Put the email transaction ID into the database FUTURE PHASE
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_POST, 1);
curl_setopt( $ch, CURLOPT_POSTFIELDS, $myvars);
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
error_log (curl_exec( $ch ));
I tried the body variable two ways. One urlencoded, one not. Here are the responses from both tries.
[05-Dec-2020 10:20:55 America/Boise] Mailer API Variables: Array
[05-Dec-2020 10:20:56 America/Boise] Your email has {placeholders} in it, but you have not specified their replacements in the body parameter, which was: ---+%0A+firstname%3AJohn%0A
[05-Dec-2020 10:22:10 America/Boise] Mailer API Variables: Array
[05-Dec-2020 10:22:10 America/Boise] Your email has {placeholders} in it, but you have not specified their replacements in the body parameter, which was: ---
firstname:John
According to the docs, CURLOPT_POSTFIELDS takes either an urlencoded string or an array. Yours is neither, since the string you give contains spaces.
An array seems easier:
$myvars = [
"recipient" => $email,
"promotion_name" => "Welcome",
"body" => "--- \nname: Some YAML data\n"
];
By the way, you seem to not show your actual code. The error message you give says your YAML starts with --- but it doesn't in your code. The error implies that you simply forgot to include the linebreak after --- in your string.
$data = file_get_contents("http://randomword.setgetgo.com/get.php");
var_dump($data);
I keep getting false when sending this get request, anyone have an idea why?
It works just fine with a simple php script I wrote hosted from the same domain, might that be the issue, how do I go about sending a get request to this API if that is the case?
I tried using curl as well with the same result. It works with my test script but not the API.
As noted in the various comments above, the code originally posted works fine for me but not for the OP - most likely due to a restriction placed upon various standard PHP functions by the webhost. As an alternative, cURL should be able to retrieve the content unless a similar restriction has been placed on standard curl functions too.
$url='http://randomword.setgetgo.com/get.php';
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_HEADER, 0 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_USERAGENT, 'curl-wordfetcher' );
$result = curl_exec( $ch );
if( curl_errno( $ch ) ) echo 'Curl error: ' . curl_error( $ch );
curl_close( $ch );
print_r( $result );
I am having trouble getting Google Cloud Messaging for Android working.
I have had it working before but it decides to stop working after the first couple of times.
In order to get it working again I have to delete my API key and recreate it.
I am using PHP with a SERVER API key with a IP whitelist of ::/0 (All IPv6 apparently)
Note: My android app requests a device message key each time the app is opened (Usually returns the same message key)
The Error I get is: Unauthorized Error 401
When I got to the following url to check my app message id i get 'invalid token'.
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=APA91bHuQEWGsvlRUhlSztNpqLVOZQGZPiGFHjQw2plcF-z8t29zvNNgNoDiRe-CbY9Fb-XcPQAFqJvy4HBfWTrTPPpzcY3pd5vX38WGalOsZ5iDiJeglpafLTC7eFkN4UA9JPKWZ4lqNiGLoH3w8W_GpFAFW5F-kLLzcbrPxwSFqyfUpmM8-14
The PHP code I am using is:
$data = array( 'message' => 'Hello World!222!' );
$ids = array('APA91bHuQEWGsvlRUhlSztNpqLVOZQGZPiGFHjQw2plcF-z8t29zvNNgNoDiRe-CbY9Fb-XcPQAFqJvy4HBfWTrTPPpzcY3pd5vX38WGalOsZ5iDiJeglpafLTC7eFkN4UA9JPKWZ4lqNiGLoH3w8W_GpFAFW5F-kLLzcbrPxwSFqyfUpmM8-14');
$apiKey = 'AIzaSyATkp_UTZh....'; //obviously the complete key is used...
$url = 'https://android.googleapis.com/gcm/send';
$post = array('registration_ids' => $ids, 'data' => $data);
$headers = array( 'Authorization: key=' . $apiKey, 'Content-Type: application/json');
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $post ) );
$result = curl_exec( $ch );
if ( curl_errno( $ch ) )
{
echo 'GCM error: ' . curl_error( $ch );
}
curl_close( $ch );
echo $result;
Thanks for any help given.
EDIT: It seems to work since I unregistered my device and reregistered it with GCM. I am not sure if this is a permanent fix but it works for now.
I have php script hosted in ftp server.
Its accessed from android app.
I did enabled Google Cloud Messaging in android and also php script.
So I want to send message every one hour.
So I need php schedule for trigger every one hour.
Message is constant.
My php code is:
<?php
define( "API_ACCESS_KEY", "***********************");
// Message to be sent
$message = "welcome to android app";
//RegistrationIds
$registrationid = "******************";
//call to gcm notification
send_push_notification($registrationid,$message);
//gcm push notification function
function send_push_notification($registrationids,$messages){
//GCM Implementation Code
// Set POST variables
$url = "https://android.googleapis.com/gcm/send";
$fields = array(
'registration_ids' => array($registrationids),
'data' => array( "message" => $messages ),
);
$headers = array(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $url );
cur_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
// Execute post
$result = curl_exec($ch);
// Close connection
curl_close($ch);
echo $result;
}
?>
I want to call send push notification method every one hour.
You can use cron job for this. You dont have to add anything to the PHP script. Just running it every hour will solve the issue. Below is how you can add a cronjob. I believe you are on a Linux server.
0 * * * * /usr/bin/php /path/to/your/php/script.php
See this link to see how you can add/edit/delete cron tab - http://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/
What i'm trying to achieve is this:
1st- I want to query a page like google but without filling it's search filed manually
2nd- I want to get the result and save it to a database
I saw an example of doing this with C# here
http://www.farooqazam.net/c-sharp-auto-click-button-and-auto-fill-form/comment-page-1/#comment-27256
but i'd like to do it with php, can you help me please?
Thanks
You should use cURL to do so, not only because it is way faster than file_get_contents, but also because it has many more features. Another reason to use it is that, as Xeoncross correctly mentioned in the comments, file_get_contents may be disabled by your webhost for security reasons.
A basic example would be this one:
$curl_handle = curl_init();
curl_setopt( $curl_handle, CURLOPT_URL, 'http://example.com' );
curl_exec( $curl_handle ); // Execute the request
curl_close( $curl_handle );
If you need the return data from the request, you need to specify the CURLOPT_RETURNTRANSFER option:
$curl_handle = curl_init();
curl_setopt( $curl_handle, CURLOPT_URL, 'http://example.com' );
curl_setopt( $curl_handle, CURLOPT_RETURNTRANSFER, true ); // Fetch the contents too
$html = curl_exec( $curl_handle ); // Execute the request
curl_close( $curl_handle );
There are tons of cURL options, for example, you can set a request timeout:
curl_setopt( $curl_handle, CURLOPT_CONNECTTIMEOUT, 2 ); // 2 second timeout
For a reference of all options see the curl_setopt() reference.
$html = file_get_contents('http://example.com');
is the simplest version you'll get.
<?php
$r = new HttpRequest('http://example.com/feed.rss', HttpRequest::METH_GET);
$r->setOptions(array('lastmodified' => filemtime('local.rss')));
$r->addQueryData(array('category' => 3));
try {
$r->send();
if ($r->getResponseCode() == 200) {
file_put_contents('local.rss', $r->getResponseBody());
}
} catch (HttpException $ex) {
echo $ex;
}
?>
From the php manual...
You can use PHP CUrl, for detailed manupulations with the site you access!
you can even perform get and posts on the site you access, or use services from different sites (in case the site provides services!).
If you find the name of the field (q) you want to fill on the remote page (Google), you can fill it by using GET syntax:
http://www.google.com/?q=hello