Google Directory API を使って CLI アプリケーション を作る

What's this

Google CLI Client (googlectl) using Directory API and Cliff

API and Library Desctiption
G Suite Admin SDK - Directory API The Directory API lets you perform administrative operations on users, groups, organizational units, and devices in your account.
Cliff Command Line Interface Formulation Framework provided by OpenStack Oslo Project

Function

Command Description
user list listing users in your domain
group list listing groups in your domain
group member list listing members of the group
user show show user information details
group show show group information details

Install

GitHub

github.com

How it works

List command example

You can get user list using Google Directory API.

$ googlectl user list
+-----------------------------+---------+
| PrimaryEmail                | isAdmin |
+-----------------------------+---------+
| alice@yourdomain.com        | False   |
| bob@yourdomain.com          | True    |
+-----------------------------+---------+

1. Authentication and Authorization (OAuth 2.0)

Using OAuth 2.0 to Access Google APIs

https://developers.google.com/identity/protocols/OAuth2

Google APIs use the OAuth 2.0 protocol for authentication and authorization. Google supports common OAuth 2.0 scenarios such as those for web server, installed, and client-side applications.

This App (Google APIs) uses OAuth2.0 Client ID

netflow dashboard

  • credentials.py

Get credentails using authorization flow.

ref: https://developers.google.com/admin-sdk/directory/v1/quickstart/python

SCOPES = [
    'https://www.googleapis.com/auth/admin.directory.user',
    'https://www.googleapis.com/auth/admin.directory.group',
    'https://www.googleapis.com/auth/admin.directory.group.member'
]
CLIENT_SECRET_FILE = './client_secret.json'
APPLICATION_NAME = 'Google Directory API Python'

def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'admin-directory_v1-python-quickstart.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials
  • libgooglectl.py

Initialize the Client Class and set credentials.

class Client(object):
    def __init__(self):
        self.credentials = googlectl.credentials.get_credentials()
        self.http = self.credentials.authorize(httplib2.Http())
        self.service = discovery.build(
            'admin', 'directory_v1', http=self.http, cache_discovery=False)

2. Get data (G Suite Admin SDK Directory API)

  • libgooglectl.py

Get user list using Google Directory API and define colums you want to output ("primaryEmail", "isAdmin")

    def list_users(self, number):
        result = self.service.users().list(
            customer='my_customer', maxResults=number,
            orderBy='email').execute()
        users = result.get('users', [])
        if not users:
            return {}
        users = {
            user['primaryEmail']: user['isAdmin']
            for user in result['users']
        }
        return users

See Directory API Response belows.

Directory API reference : Users: list

https://developers.google.com/admin-sdk/directory/v1/reference/users/list?hl=ja

Request HTTP request

GET https://www.googleapis.com/admin/directory/v1/users

Receive Response

{
 "kind": "admin#directory#users",
 "etag": etag,
 "users": [
  {
   "primaryEmail": "alice@yourdomain.com",
   "isAdmin": false,
   .
   .
  },
  {
   "primaryEmail": "bob@yourdomain.com",
   "isAdmin": true,
   .
   .
  }
 ]
}

3. Return data to be formatted (Cliff)

List Commands

https://docs.openstack.org/cliff/latest/user/list_commands.html

Lister The cliff.lister.Lister base class API extends Command to allow take_action() to return data to be formatted using a user-selectable formatter. Subclasses should provide a take_action() implementation that returns a two member tuple containing a tuple with the names of the columns in the dataset and an iterable that will yield the data to be output.

  • list.py

take_action() implementation

class UserList(Lister):
    def get_parser(self, prog_name):
        parser = super(UserList, self).get_parser(prog_name)
        parser = _append_global_args(parser)
        return parser

    def take_action(self, parsed_args):
        client = googlectl.libgooglectl.Client()
        users = client.list_users(parsed_args.number)
        return (('PrimaryEmail', 'isAdmin'), (
            (primaryemail, users[primaryemail]) for primaryemail in users))

List Output Formatters cliff is delivered with two output formatters for list commands. Lister adds a command line switch to let the user specify the formatter they want, so you don’t have to do any extra work in your application.

4. Command output

Finally you can see formatted data output (The table formatter : default)

$ googlectl user list
+-----------------------------+---------+
| PrimaryEmail                | isAdmin |
+-----------------------------+---------+
| alice@yourdomain.com        | False   |
| bob@yourdomain.com          | True    |
+-----------------------------+---------+

Reference

  • OpenStack Osloを使おう - cliff編

https://www.slideshare.net/h-saito/openstack-oslo-cliff

  • cliff – Command Line Interface Formulation Framework

https://docs.openstack.org/cliff/latest/index.html

https://developers.google.com/api-client-library/python/guide/aaa_oauth