简体   繁体   中英

How to turn on/off CloudSQL instances using Python3

I'm trying to use a Python script to turn on/off a CloudSQL Instance in GoogleCloud. I've finally found a way to do it, using the GoogleCloudAPI, in Shell:

### shell script
ACCESS_TOKEN="$(gcloud auth print-access-token)"
ACTIVATION_POLICY="ALWAYS/NEVER" # Use 'ALWAYS' to turn on, 'NEVER' to turn off
curl --header "Authorization: Bearer ${ACCESS_TOKEN}"  --header 'Content-Type: application/json' --data '{"settings" : {"activationPolicy" : "${ACTIVATION_POLICY}"}}' -X PATCH https://www.googleapis.com/sql/v1beta4/projects/${PROJECT_ID}/instances/${INSTANCE_ID}

So, great, problem solved... except I cannot use 'gcloud auth print-access-token' on the machine I'm running the script in, so that solves nothing. I found a question from 2017 trying to generate this 'access-token' using Python as well, which apparently didn't work either.

I need to be able to generate this 'access-token' using Python itself. I've been looking around in the Google's documentation but I still haven't managed to find anything related to that, closest I found was using oauth2 and googleapiclient to get the list of instances running, but can't seem to change activation policies from there:

### python3 script
from google.oauth2 import service_account
import googleapiclient.discovery
SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'
credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)
sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta4', credentials=credentials)
response = sqladmin.instances().get(project=PROJECT_ID, instance=INSTANCE_ID).execute()

The documentation doesn't make it clear how to use either tool to turn off the CloudSQL instance though, or at least none that I could find do. The above code returns me a JSON file and I can see the 'activationPolicy' there, under settings. I can't find a way to 'change it' though.

Managed to follow @norbjd suggestion and find a 'patch' method, and gave 'SQL Admin' permission to my credentials, so it can now use the sqladmin API. Tried to patch it using the following code:

instance = sqladmin.instances().patch(project=PROJECT_ID, instance=INSTANCE_ID)
instance.data = {"settings" : {"activationPolicy" : "NEVER"}} #also tried with it in a string, like this: instance.data = {"settings" : {"activationPolicy" : "NEVER"}}
instance.headers['Content-Type'] = 'application/json'
instance.execute()

Considering instance.data didn't exist prior to that, but instance.headers did:

{'accept': 'application/json', 'accept-encoding': 'gzip, deflate', 'user-agent': '(gzip)', 'x-goog-api-client': 'gdcl/1.7.11 gl-python/3.6.9'}

After the execute, though, nothing seemed to happen. It did not change the actual activationPolicy.

In the end, the problem was solved using the ACCESS_TOKEN and making a Python request using the requests module. If you try to get an ACCESS_TOKEN from your credentials just after generating them, you won't be getting any, but if you actually use your credentials with the googleapiclient.discovery, this updates that object with a valid access token, that can then be used in a Python request, as follows:

from google.oauth2 import service_account
import googleapiclient.discovery
import json
import requests

PROJECT_ID = '{PROJECT_ID_HERE}'
INSTANCE_ID = '{INSTANCE_ID_HERE}'

SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'
credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta4', credentials=credentials)
response = sqladmin.instances().get(project=PROJECT_ID, instance=INSTANCE_ID).execute()
print(json.dumps(response))

access_token = credentials.token # Now that the credentials were used, they have a valid access_token associated with them!

activation_policy = 'NEVER' # or 'ALWAYS'

url = "https://www.googleapis.com/sql/v1beta4/projects/{PROJECT_ID}/instances/{INSTANCE_ID}".format(PROJECT_ID=PROJECT_ID, INSTANCE_ID=INSTANCE_ID)
header = {
    "Authorization" : "Bearer {}".format(access_token), 
    "Content-Type" : "application/json"
}
data = {
    "settings" : {
        "activationPolicy" : activation_policy
    }
}
response = requests.patch(url, headers=header, data=json.dumps(data))
print(response.text)

All it took was to actually use the credentials for something before attempting to retrieve the ACCESS_TOKEN

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM