Skip to content

Commit e5234a9

Browse files
feat: VM Indentity samples added. (#5884)
* feat: VM Indentity samples added. Co-authored-by: Charles Engelke <[email protected]>
1 parent 1ab7826 commit e5234a9

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

compute/metadata/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
requests==2.25.1
2+
google-auth==1.30.0

compute/metadata/vm_identity.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python
2+
# Copyright 2021 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# [START compute_vm_identity_verify_token]
17+
import pprint
18+
19+
import google.auth.transport.requests
20+
from google.oauth2 import id_token
21+
22+
# [END compute_vm_identity_verify_token]
23+
24+
# [START compute_vm_identity_acquire_token]
25+
import requests
26+
27+
AUDIENCE_URL = 'http://www.example.com'
28+
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
29+
METADATA_VM_IDENTITY_URL = 'http://metadata.google.internal/computeMetadata/v1/' \
30+
'instance/service-accounts/default/identity?' \
31+
'audience={}&format={}&licenses={}'
32+
FORMAT = 'full'
33+
LICENSES = 'TRUE'
34+
35+
36+
def acquire_token(audience: str = AUDIENCE_URL) -> str:
37+
# Construct a URL with the audience and format.
38+
url = METADATA_VM_IDENTITY_URL.format(audience, FORMAT, LICENSES)
39+
40+
# Request a token from the metadata server.
41+
r = requests.get(url, headers=METADATA_HEADERS)
42+
# Extract and return the token from the response.
43+
r.raise_for_status()
44+
return r.text
45+
46+
47+
# [END compute_vm_identity_acquire_token]
48+
49+
# [START compute_vm_identity_verify_token]
50+
51+
52+
def verity_token(token: str, audience: str) -> dict:
53+
"""Verify token signature and return the token payload"""
54+
request = google.auth.transport.requests.Request()
55+
payload = id_token.verify_token(token, request=request, audience=audience)
56+
return payload
57+
58+
# [END compute_vm_identity_verify_token]
59+
60+
61+
if __name__ == '__main__':
62+
token_ = acquire_token()
63+
print("Received token:", token_)
64+
print("Token verification:")
65+
pprint.pprint(verity_token(acquire_token(AUDIENCE_URL), AUDIENCE_URL))

compute/metadata/vm_identity_test.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2021 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import pytest
15+
import requests
16+
17+
import vm_identity
18+
19+
AUDIENCE = 'http://www.testing.com'
20+
21+
22+
def test_vm_identity():
23+
try:
24+
# Check if we're running in a GCP VM:
25+
r = requests.get('http://metadata.google.internal/computeMetadata/v1/project/project-id',
26+
headers={'Metadata-Flavor': 'Google'})
27+
project_id = r.text
28+
except requests.exceptions.ConnectionError:
29+
# Guess we're not running in a GCP VM, we need to skip this test
30+
pytest.skip("Test can only be run inside GCE VM.")
31+
return
32+
33+
token = vm_identity.acquire_token(AUDIENCE)
34+
assert isinstance(token, str) and token
35+
verification = vm_identity.verity_token(token, AUDIENCE)
36+
assert isinstance(verification, dict) and verification
37+
assert verification['aud'] == AUDIENCE
38+
assert verification['email_verified']
39+
assert verification['iss'] == 'https://accounts.google.com'
40+
assert verification['google']['compute_engine']['project_id'] == project_id

0 commit comments

Comments
 (0)