def get_service_account_credentials(client_id_key): # Figure out what environment we're running in and get some preliminary # information about the service account. credentials, _ = google.auth.default(scopes=[IAM_SCOPE]) if isinstance(credentials, google.oauth2.credentials.Credentials): raise Exception("make_iap_request is only supported for service " "accounts.") # For service account's using the Compute Engine metadata service, # service_account_email isn't available until refresh is called. credentials.refresh(Request()) signer_email = credentials.service_account_email if isinstance(credentials, google.auth.compute_engine.credentials.Credentials): signer = google.auth.iam.Signer(Request(), credentials, signer_email) else: # A Signer object can sign a JWT using the service account's key. signer = credentials.signer # Construct OAuth 2.0 service account credentials using the signer # and email acquired from the bootstrap credentials. return google.oauth2.service_account.Credentials( signer, signer_email, token_uri=OAUTH_TOKEN_URI, additional_claims={"target_audience": may_get_env_var(client_id_key)})
def test_with_scopes(self, get, utcnow): get.side_effect = [ { # First request is for sevice account info. "email": "*****@*****.**", "scopes": ["one", "two"], }, { # Second request is for the token. "access_token": "token", "expires_in": 500, }, ] # Refresh credentials credentials = self.credentials.with_scopes(("new_scope_one", "new_scope_two")) credentials.refresh(None) # Check that scopes are passed to metadata service expected_path = ( "instance/service-accounts/service-account%40example.com/token" "?scopes=new_scope_one%2Cnew_scope_two") get.assert_called_with(None, expected_path) # Check that the credentials have the token and proper expiration assert credentials.token == "token" assert credentials.expiry == (utcnow() + datetime.timedelta(seconds=500)) # Check the credential info assert credentials.service_account_email == "*****@*****.**" assert credentials._scopes == ("new_scope_one", "new_scope_two") # Check that the credentials are valid (have a token and are not # expired) assert credentials.valid
def check_deploy_status(args): print("check deployment status") # Figure out what environment we're running in and get some preliminary # information about the service account. credentials, _ = google.auth.default(scopes=[IAM_SCOPE]) if isinstance(credentials, google.oauth2.credentials.Credentials): raise Exception('make_iap_request is only supported for service ' 'accounts.') # For service account's using the Compute Engine metadata service, # service_account_email isn't available until refresh is called. credentials.refresh(Request()) signer_email = credentials.service_account_email if isinstance(credentials, google.auth.compute_engine.credentials.Credentials): signer = google.auth.iam.Signer(Request(), credentials, signer_email) else: # A Signer object can sign a JWT using the service account's key. signer = credentials.signer # Construct OAuth 2.0 service account credentials using the signer # and email acquired from the bootstrap credentials. service_account_credentials = google.oauth2.service_account.Credentials( signer, signer_email, token_uri=OAUTH_TOKEN_URI, additional_claims={'target_audience': may_get_env_var("CLIENT_ID")}) google_open_id_connect_token = get_google_open_id_connect_token( service_account_credentials) # Wait up to 30 minutes for IAP access test. retry_credit = 180 status_code = 0 while retry_credit > 0: retry_credit -= 1 sleep(10) try: resp = requests.request( METHOD, "https://%s.endpoints.%s.cloud.goog" % (args.deployment, args.project), headers={ 'Authorization': 'Bearer {}'.format(google_open_id_connect_token) }) status_code = resp.status_code if resp.status_code == 200: break except Exception: print("IAP not ready, exception caught, retry credit: %s" % retry_credit) continue print("IAP not ready, retry credit: %s" % retry_credit) if status_code != 200: raise RuntimeError( "IAP endpoint not ready after 30 minutes, time out...")
def main(unparsed_args=None): parser = argparse.ArgumentParser( description="Output signal of kubeflow service readiness.") parser.add_argument("--url", default="", type=str, help="kubeflow IAP-protected url") parser.add_argument("--client_id", default="", type=str, help="Service account json credential file") args = parser.parse_args(args=unparsed_args) if args.url == "" or args.client_id == "": logging.info("Url or client_id is empty, exit") return # Figure out what environment we're running in and get some preliminary # information about the service account. credentials, _ = google.auth.default(scopes=[IAM_SCOPE]) if isinstance(credentials, google.oauth2.credentials.Credentials): raise Exception('make_iap_request is only supported for service ' 'accounts.') # For service account's using the Compute Engine metadata service, # service_account_email isn't available until refresh is called. credentials.refresh(Request()) signer_email = credentials.service_account_email if isinstance(credentials, google.auth.compute_engine.credentials.Credentials): # Since the Compute Engine metadata service doesn't expose the service # account key, we use the IAM signBlob API to sign instead. # In order for this to work: # # 1. Your VM needs the https://www.googleapis.com/auth/iam scope. # You can specify this specific scope when creating a VM # through the API or gcloud. When using Cloud Console, # you'll need to specify the "full access to all Cloud APIs" # scope. A VM's scopes can only be specified at creation time. # # 2. The VM's default service account needs the "Service Account Actor" # role. This can be found under the "Project" category in Cloud # Console, or roles/iam.serviceAccountActor in gcloud. signer = google.auth.iam.Signer(Request(), credentials, signer_email) else: # A Signer object can sign a JWT using the service account's key. signer = credentials.signer # Construct OAuth 2.0 service account credentials using the signer # and email acquired from the bootstrap credentials. service_account_credentials = google.oauth2.service_account.Credentials( signer, signer_email, token_uri=OAUTH_TOKEN_URI, additional_claims={'target_audience': args.client_id}) token_refresh_time = 0 last_status = -1 config.load_incluster_config() coreApi = client.CoreV1Api() while True: if time() > token_refresh_time: # service_account_credentials gives us a JWT signed by the service # account. Next, we use that to obtain an OpenID Connect token, # which is a JWT signed by Google. google_open_id_connect_token = get_google_open_id_connect_token( service_account_credentials) token_refresh_time = time() + 1800 url_status = metric_update(args, google_open_id_connect_token) if url_status != last_status: last_status = url_status # get service centraldashboard, attach event to it. svcs = coreApi.list_namespaced_service( 'kubeflow', label_selector="app=centraldashboard") while len(svcs.to_dict()['items']) == 0: logging.info("Service centraldashboard not ready...") sleep(10) svcs = coreApi.list_namespaced_service( 'kubeflow', label_selector="app=centraldashboard") uid = svcs.to_dict()['items'][0]['metadata']['uid'] kf_status = "up" if url_status == 1 else "down" new_event = V1Event( action="Kubeflow service status update: " + kf_status, api_version="v1", kind="Event", message="Service " + kf_status + "; service url: " + args.url, reason="Kubeflow Service is " + kf_status, involved_object=client.V1ObjectReference( api_version="v1", kind="Service", name="centraldashboard", namespace="kubeflow", uid=uid), metadata=V1ObjectMeta(generate_name='kubeflow-service.', ), type="Normal") event = coreApi.create_namespaced_event("kubeflow", new_event) print("New status event created. action='%s'" % str(event.action)) # Update status every 10 sec sleep(10)
def main(unparsed_args=None): parser = argparse.ArgumentParser( description="Output signal of kubeflow service readiness.") parser.add_argument("--url", default="", type=str, help="kubeflow IAP-protected url") parser.add_argument("--client_id", default="", type=str, help="Service account json credential file") args = parser.parse_args(args=unparsed_args) if args.url == "": sleep(2000) return # Figure out what environment we're running in and get some preliminary # information about the service account. credentials, _ = google.auth.default(scopes=[IAM_SCOPE]) if isinstance(credentials, google.oauth2.credentials.Credentials): raise Exception('make_iap_request is only supported for service ' 'accounts.') # For service account's using the Compute Engine metadata service, # service_account_email isn't available until refresh is called. credentials.refresh(Request()) signer_email = credentials.service_account_email if isinstance(credentials, google.auth.compute_engine.credentials.Credentials): # Since the Compute Engine metadata service doesn't expose the service # account key, we use the IAM signBlob API to sign instead. # In order for this to work: # # 1. Your VM needs the https://www.googleapis.com/auth/iam scope. # You can specify this specific scope when creating a VM # through the API or gcloud. When using Cloud Console, # you'll need to specify the "full access to all Cloud APIs" # scope. A VM's scopes can only be specified at creation time. # # 2. The VM's default service account needs the "Service Account Actor" # role. This can be found under the "Project" category in Cloud # Console, or roles/iam.serviceAccountActor in gcloud. signer = google.auth.iam.Signer(Request(), credentials, signer_email) else: # A Signer object can sign a JWT using the service account's key. signer = credentials.signer # Construct OAuth 2.0 service account credentials using the signer # and email acquired from the bootstrap credentials. service_account_credentials = google.oauth2.service_account.Credentials( signer, signer_email, token_uri=OAUTH_TOKEN_URI, additional_claims={'target_audience': args.client_id}) token_refresh_time = 0 while True: if time() > token_refresh_time: # service_account_credentials gives us a JWT signed by the service # account. Next, we use that to obtain an OpenID Connect token, # which is a JWT signed by Google. google_open_id_connect_token = get_google_open_id_connect_token( service_account_credentials) token_refresh_time = time() + 1800 metric_update(args, google_open_id_connect_token) # Update status every 10 sec sleep(10)