GCE - Switch ON and OFF a VM from API request - php

I'm figuring out if there is a way to switch ON and OFF an instance on Google Compute Engine directly by API (hosted on app engine with PHP).
I've found this documentation:
https://cloud.google.com/compute/docs/reference/rest/v1/instances/start
But can't understand if this documentation is what really i need or not :/
EDIT:
$client = new Google_Client();
$client->setApplicationName('Google-ComputeSample/0.1');
$client->useApplicationDefaultCredentials();
$client->addScope('https://www.googleapis.com/auth/cloud-platform');
$service = new Google_Service_Compute($client);
// Project ID for this request.
$project = 'my-project';
// The name of the zone for this request.
$zone = 'europe-west3-c';
// Name of the instance resource to start.
$instance = 'name-instance';
$response = $service->instances->start($project, $zone, $instance);
print_r($response)
Get this error:
Uncaught exception 'DomainException' with message 'Could not load the default credentials. Browse to https://developers.google.com/accounts/docs/application-default-credentials for more information'
I'm trying to run this code from localhost, i think this is the problem.
If i run this code from an app engine inside my project, i suppose it will work.
But the google-php-client folder for the APIs has > 10000 files inside, so I can't push it on an app engine versione and try it :/

The document that you cite is correct for what you want to achieve, so using that API call you will start a VM instance and with the method instances.stop you will stop them. The examples for PHP are in the same document, to start [1] and to stop [2]. I hope this information helps.

Related

How to use OVH Api with Laravel

I'm working on an application that sends SMS to the customers we got.
I'm currently looking the doc (https://docs.ovh.com/fr/sms/envoyer_des_sms_avec_lapi_ovh_en_php/) => it's in french.
They're using a PHP Wrapper, but I really don't know how I can integrate the API to my Laravel Project.
Does someone know how it's working ?
First of all, install the package
composer require ovh/php-ovh-sms
Then, on the controller, you can use the API easily as stated in the documentation.
use \Ovh\Sms\SmsApi;
// Informations about your application
// You may set them to 'NULL' if you are using
// a configuraton file
$applicationKey = "your_app_key";
$applicationSecret = "your_app_secret";
$consumerKey = "your_consumer_key";
$endpoint = 'ovh-eu';
// Init SmsApi object
$Sms = new SmsApi( $applicationKey, $applicationSecret, $endpoint, $consumerKey );
// Get available SMS accounts
$accounts = $Sms->getAccounts();
dd($accounts);
There is a Laravel notification channel specifically for this provider, this will make the whole process much easier, it will allow you to use Laravel's built in notifications functionality without having to write provider specific code.
http://laravel-notification-channels.com/ovh-sms/

How to create a credential (for google sheets) on GCE with php code?

I put my php code in GCE and wanna to modify google sheets.
Google told me that i don't have to apply a extra credential by using GCP>API because there's a strategy called Application Default Credentials (ADC) will find application's credentials.
I first check the environment variable "GOOGLE_APPLICATION_CREDENTIALS" in GCE server but it's empty.
Then i follow this tutorial https://cloud.google.com/docs/authentication/production?hl=zh_TW#auth-cloud-implicit-php and install this:
composer require google/cloud-storage
I tried the code under and got some error.
namespace Google\Cloud\Samples\Auth;
// Imports GCECredentials and the Cloud Storage client library.
use Google\Auth\Credentials\GCECredentials;
use Google\Cloud\Storage\StorageClient;
function auth_cloud_explicit_compute_engine($projectId)
{
$gceCredentials = new GCECredentials();
$config = [
'projectId' => $projectId,
'credentialsFetcher' => $gceCredentials,
];
$storage = new StorageClient($config);
# Make an authenticated API request (listing storage buckets)
foreach ($storage->buckets() as $bucket) {
printf('Bucket: %s' . PHP_EOL, $bucket->name());
}
}
PHP Fatal error: Uncaught Error: Class 'GCECredentials' not found in /var/www/html/google_sheets/t2.php:5
More question:
Will this code create a json file as credential for me to access google sheets?
$gceCredentials = new GCECredentials();
Or where can i find the service account key??
Please tell me what should i do, thanks a lot.

Setup google-api-php-client to comunicate with custom google app engine API endpoint

I'm trying to configure the google-api-php-client library in my project.
I've already created a custom google app engine project that consists in a cloud endpoint. The project is called 'set-core', the service is called 'vrp API', version 'v1' and the method vrp.vrp.getSolution().
Now in my PHP code i'm following this example:
https://developers.google.com/api-client-library/php/start/get_started#building-and-calling-a-service
The problem is that in this example there's no mention how to connect to any custom service, outside Google's ones.
My PHP code is:
$client = new Google_Client();
$client->setApplicationName("set-core");
$client->setDeveloperKey("AIzaSyByd8cRJNGYC4szFLbr3**************");
$client->isAppEngine(true);
$service = new Google_Service_Appengine_Service($client);
$results = $service->vrp->vrp.vrp.getSolution($stringVehicles, $stringServices, $stringDepot);
Unfortunately, on the last line, PHP warns me:
Notice: Trying to get property of non-object (I assume it's $service).
The problem is that I don't really know how to set up all the client's params and which Service type use.
You are going to want to create an authorized HTTP client and then request your API endpoint directly with it. The AppEngine service classes you're manipulating above are not meant for this use case. Something like this should work:
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$httpClient = $client->authorize();
$response = $httpClient->request('GET', 'https://myapp.appspot.com/vrp/getSolution');
The $httpClient class is an instance of GuzzleHttp\Client, but with your Google authentication already added to it. See the documentation for making a request with Guzzle.
I hope this helps!

Bad Request when creating new container in Tag-Manager

I use the php sdk to interact with Google Tag Manager. When I run this code
$client = new \Google_Client();
$client->setClientId('xxxx');
$client->setClientSecret('xxxx');
$client->setAccessToken($token);
$container = new \Google_Service_TagManager_Container();
$container->setName('a-name');
$container->setTimeZoneCountryId('America/Los_Angeles');
$container->setTimeZoneId('US');
$container->setUsageContext(array('web', 'android', 'ios'));
$tagManager = new \Google_Service_TagManager($client);
$tagManager->accounts_containers->create('xxx', $container);
then an exception is raised: Error calling POST https://www.googleapis.com/tagmanager/v1/accounts/xxx/containers: (400) Bad Request.
The container data are the same as in the Google Developer console. A sample-request in the Google Developer Console creates the same Bad Request error.
Any ideas? Is it a API bug?
This post is quit old and my answer is related to the tag manager api v2 but i also struggelt with creating an container (in v2) and just accomplished the task. I share my code here because when i searched for my problem, i endet up here and found no answer... Maybe it helps someone.
So basically after doing all of the auth stuff, here is how you create an container using tag manager v2 api:
$container = new Google_Service_TagManager_Container();
$container->setUsageContext(['web']);
$container->setName('yourContainerName');
$container->setNotes('yourContainerNotes');
$accountId = 'yourAccountId';
try {
$accountContainer = $tagManager->accounts_containers->create('accounts/'.$accountId, $container);
} catch(Exception $e) {
$this->printH($e->getMessage());
$this->printH($e->getCode());
}

Save to local Google Datastore with PHP

The following code inserts an entity into the remote Google Datastore:
require_once('google-api-php-client/src/Google_Client.php');
require_once('google-api-php-client/src/contrib/Google_DatastoreService.php');
$client = new Google_Client();
$client -> setApplicationName("myApp");
$serviceAccount = 'myServiceAccount#developer.gserviceaccount.com';
$key = file_get_contents('super/secret/encryptedKey-privatekey.p12');
$client -> setAssertionCredentials(new Google_AssertionCredentials(
$serviceAccount,
array('https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/datastore'), $key));
$datastore = new Google_DatastoreService($client);
$path = new Google_KeyPathElement();
$path -> setName('testName');
$path -> setKind('testKind');
$key = new Google_Key();
$key -> setPath(array($path));
$entities = new Google_Entity();
$entities -> setKey($key);
$mutation = new Google_Mutation();
$mutation -> setInsert(array($entities));
$blindWrite = new Google_BlindWriteRequest();
$blindWrite -> setMutation($mutation);
$datastore -> datasets -> blindWrite('myApp', $blindWrite);
Now this is not really ideal for local development, so I changed the 'basePath' in google-api-php-client/src/config.php from
'basePath' => 'https://www.googleapis.com',
to
'basePath' => 'http://localhost:53290',
which is my API server according to the app launcher log.
Unfortunately, this does not work and any requests to the local API server result in the following error:
Fatal error: Uncaught exception 'Google_ServiceException' with message 'Error calling POST http://localhost:53290/datastore/v1beta1/datasets/myApp/blindWrite: (400) HTTP requires CRLF terminators' in ***\google-api-php-client\src\io\Google_REST.php:66
However, accessing http://localhost:53290 works and returns:
{app_id: dev~myApp, rtok: '0'}
Does anybody know what's causing this error? The request is exactly the same and I know that the local datastore is working in other languages.
Caveat: I have not developed in PHP on GAE, only in python and java.
According to this answer the PHP runtime currently cannot access the GAE-datastore; instead it uses Google Cloud Datastore which is accessed differently. (Just wanted to clarify this, since you tagged your question with gae-datastore)
AFIAK, the GAE development server does not support Google Cloud Datastore (which you are using via Google_DatastoreService.php). In order to simulate Google Cloud Datastore locally you will need to run the Google Cloud Datastore development server. -- However, if you can even use this depends on whether the PHP client uses their protocal buffer or their JSON API. Only the former is supported. See note on that page. So you might be stuck at this point.
Assuming you can use the local devserver:
I don't know what basepath in google-api-php/client/src/config.php is referring to and if changing it is the way to go when you are running the Google Cloud Datastore local devserver. The docs for the devserver state that you should modify the environment variables DATASTORE_HOST and DATASTORE_DATASET.
(BTW: I believe the API server entry in your app launcher log refers to Google Cloud Endpoints which aren't related to your problem.)
This is the easiest workaround if someone wants to use a different Cloud Datastore for development and production using PHP:
Create two applications:
myApp
myApp-dev
Activate the Datastore API for both applications. I was a little surprised but you can access a datastore from any application as long as you have the correct service-account-id and private key.
Implement a simple switch:
const DATASTORE_APP_NAME_PRODUCTION = 'myApp';
const DATASTORE_SERVICE_ACCOUNT_NAME_PRODUCTION =
'production-service-account-id#developer.gserviceaccount.com';
const DATASTORE_APP_NAME_DEVELOPMENT = 'myApp-dev';
const DATASTORE_SERVICE_ACCOUNT_NAME_DEVELOPMENT =
'dev-service-account-id#developer.gserviceaccount.com';
if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'],
'Google App Engine') !== false) {
$runMode = 'PRODUCTION';
} else {
$runMode = 'DEVELOPMENT';
}
Then do something like this when you want access the Cloud Datastore in your application:
$serviceAccount = constant('DATASTORE_SERVICE_ACCOUNT_NAME_'.$runMode);
$appName = constant('DATASTORE_APP_NAME_'.$runMode);
$key = file_get_contents('secret/path/'.$runMode.'-privatekey.p12');
$client -> setAssertionCredentials(
new Google_AssertionCredentials($serviceAccount,
array('https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/datastore'), $key));
I have recently created a library that can handle this: https://github.com/pwhelan/datachore. The actual magic is in: https://github.com/pwhelan/datachore/blob/master/src/Datastore/GoogleRemoteApi.php.
The code works just as well once it is deployed.

Categories