195 lines
7.6 KiB
Python
195 lines
7.6 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from libcloud.common.google import GoogleOAuth2Credential
|
|
from libcloud.container.providers import Provider
|
|
from libcloud.container.drivers.kubernetes import KubernetesContainerDriver
|
|
from libcloud.common.google import GoogleResponse
|
|
from libcloud.common.google import GoogleBaseConnection
|
|
API_VERSION = 'v1'
|
|
|
|
|
|
class GKEResponse(GoogleResponse):
|
|
pass
|
|
|
|
|
|
class GKEConnection(GoogleBaseConnection):
|
|
"""
|
|
Connection class for the GKE driver.
|
|
|
|
GKEConnection extends :class:`google.GoogleBaseConnection` for 3 reasons:
|
|
1. modify request_path for GKE URI.
|
|
2. Implement gce_params functionality described below.
|
|
3. Add request_aggregated_items method for making aggregated API calls.
|
|
|
|
"""
|
|
host = 'container.googleapis.com'
|
|
responseCls = GKEResponse
|
|
|
|
def __init__(self, user_id, key, secure, auth_type=None,
|
|
credential_file=None, project=None, **kwargs):
|
|
super(GKEConnection, self).__init__(
|
|
user_id, key, secure=secure, auth_type=auth_type,
|
|
credential_file=credential_file, **kwargs)
|
|
self.request_path = '/%s/projects/%s' % (API_VERSION, project)
|
|
self.gke_params = {}
|
|
|
|
def pre_connect_hook(self, params, headers):
|
|
"""
|
|
Update URL parameters with values from self.gke_params.
|
|
|
|
@inherits: :class:`GoogleBaseConnection.pre_connect_hook`
|
|
"""
|
|
params, headers = super(GKEConnection, self).pre_connect_hook(params,
|
|
headers)
|
|
if self.gke_params:
|
|
params.update(self.gke_params)
|
|
return params, headers
|
|
|
|
def request(self, *args, **kwargs):
|
|
"""
|
|
Perform request then do GKE-specific processing of URL params.
|
|
|
|
@inherits: :class:`GoogleBaseConnection.request`
|
|
"""
|
|
response = super(GKEConnection, self).request(*args, **kwargs)
|
|
|
|
# If gce_params has been set, then update the pageToken with the
|
|
# nextPageToken so it can be used in the next request.
|
|
if self.gke_params:
|
|
if 'nextPageToken' in response.object:
|
|
self.gke_params['pageToken'] = response.object['nextPageToken']
|
|
elif 'pageToken' in self.gke_params:
|
|
del self.gke_params['pageToken']
|
|
self.gke_params = None
|
|
|
|
return response
|
|
|
|
|
|
class GKEContainerDriver(KubernetesContainerDriver):
|
|
"""
|
|
GKE Container Driver class.
|
|
|
|
This is the primary driver for interacting with Google Container
|
|
Engine. It contains all of the standard libcloud methods,
|
|
plus additional ex_* methods for more features.
|
|
|
|
Note that many methods allow either objects or strings (or lists of
|
|
objects/strings). In most cases, passing strings instead of objects
|
|
will result in additional GKE API calls.
|
|
"""
|
|
connectionCls = GKEConnection
|
|
api_name = 'google'
|
|
name = "Google Container Engine"
|
|
type = Provider.GKE
|
|
website = 'https://container.googleapis.com'
|
|
supports_clusters = True
|
|
|
|
AUTH_URL = "https://container.googleapis.com/auth/"
|
|
|
|
def __init__(self, user_id, key=None, datacenter=None, project=None,
|
|
auth_type=None, scopes=None, credential_file=None,
|
|
host=None, port=443, **kwargs):
|
|
"""
|
|
:param user_id: The email address (for service accounts) or Client ID
|
|
(for installed apps) to be used for authentication.
|
|
:type user_id: ``str``
|
|
|
|
:param key: The RSA Key (for service accounts) or file path containing
|
|
key or Client Secret (for installed apps) to be used for
|
|
authentication.
|
|
:type key: ``str``
|
|
|
|
:keyword datacenter: The name of the datacenter (zone) used for
|
|
operations.
|
|
:type datacenter: ``str``
|
|
|
|
:keyword project: Your GKE project name. (required)
|
|
:type project: ``str``
|
|
|
|
:keyword auth_type: Accepted values are "SA" or "IA" or "GKE"
|
|
("Service Account" or "Installed Application" or
|
|
"GKE" if libcloud is being used on a GKE instance
|
|
with service account enabled).
|
|
If not supplied, auth_type will be guessed based
|
|
on value of user_id or if the code is being
|
|
executed in a GKE instance.
|
|
:type auth_type: ``str``
|
|
|
|
:keyword scopes: List of authorization URLs. Default is empty and
|
|
grants read/write to Compute, Storage, DNS.
|
|
:type scopes: ``list``
|
|
|
|
:keyword credential_file: Path to file for caching authentication
|
|
information used by GKEConnection.
|
|
:type credential_file: ``str``
|
|
"""
|
|
if not project:
|
|
raise ValueError('Project name must be specified using '
|
|
'"project" keyword.')
|
|
if host is None:
|
|
host = GKEContainerDriver.website
|
|
self.auth_type = auth_type
|
|
self.project = project
|
|
self.scopes = scopes
|
|
self.zone = None
|
|
if datacenter is not None:
|
|
self.zone = datacenter
|
|
self.credential_file = credential_file or \
|
|
GoogleOAuth2Credential.default_credential_file + '.' + self.project
|
|
|
|
super(GKEContainerDriver, self).__init__(user_id, key,
|
|
secure=True, host=None,
|
|
port=None, **kwargs)
|
|
|
|
self.base_path = '/%s/projects/%s' % (API_VERSION, self.project)
|
|
self.website = GKEContainerDriver.website
|
|
|
|
def _ex_connection_class_kwargs(self):
|
|
return {'auth_type': self.auth_type,
|
|
'project': self.project,
|
|
'scopes': self.scopes,
|
|
'credential_file': self.credential_file}
|
|
|
|
def list_clusters(self, ex_zone=None):
|
|
"""
|
|
Return a list of cluster information in the current zone or all zones.
|
|
|
|
:keyword ex_zone: Optional zone name or None
|
|
:type ex_zone: ``str`` or :class:`GCEZone` or
|
|
:class:`NodeLocation` or ``None``
|
|
"""
|
|
request = "/zones/%s/clusters" % (ex_zone)
|
|
if ex_zone is None:
|
|
request = "/zones/clusters"
|
|
|
|
response = self.connection.request(request, method='GET').object
|
|
return response
|
|
|
|
def get_server_config(self, ex_zone=None):
|
|
"""
|
|
Return configuration info about the Container Engine service.
|
|
|
|
:keyword ex_zone: Optional zone name or None
|
|
:type ex_zone: ``str`` or :class:`GCEZone` or
|
|
:class:`NodeLocation` or ``None``
|
|
"""
|
|
if ex_zone is None:
|
|
ex_zone = self.zone
|
|
request = "/zones/%s/serverconfig" % (ex_zone)
|
|
|
|
response = self.connection.request(request, method='GET').object
|
|
return response
|