Skip to content

Commit

Permalink
Google sheets to IDM (#1)
Browse files Browse the repository at this point in the history
* Create/Update Users - Google sheets to idm

* Add expiration formatting and example
  • Loading branch information
mcanoy authored and oybed committed Sep 18, 2017
1 parent 9df3cce commit 2a9df18
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "ansible-stacks"]
path = ansible-stacks
url = https://github.com/rht-labs/ansible-stacks
1 change: 1 addition & 0 deletions ansible-stacks
Submodule ansible-stacks added at a68d75
17 changes: 17 additions & 0 deletions playbooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Playbooks

## load_gdrive_identities.yml
This playbook is used to retrieve identities from google sheets and insert/update users and groups into an identity manager (IPA)

Example run:

```
>>ansible-playbook -i load_gdrive_identities.yml -e google_doc_file_id=1qcp8yI -e google_doc_file_name=sample.csv -e gdrive_command_tool=gdrive -e google_service_account=labs-sa.json -e ipa_admin_user=admin -e ipa_admin_password=admin
```


**Notes**
1. The user needs to have idm rights to add/remove/modify users and groups

17 changes: 17 additions & 0 deletions playbooks/load_gdrive_identities.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
# This test covers the full feature set provided by the role

- name: Retrieve Google Sheet identies and import to IDM
hosts: ipa

# Sample vars
# vars:
# ipa_admin_password: admin
# ipa_admin_user: admin
# google_service_account: labs-sa.json
# google_doc_file_id: google-internal-id
# google_doc_file_name: google_sheet_title.csv
# gdrive_command_tool: gdrive

roles:
- idm
12 changes: 12 additions & 0 deletions roles/idm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#CREATE IDENTITIES IN AN EXISTING IDM

An ansible role that will consume a google sheet and insert that data into and existing IDM (IPA). the format of the sheet should include a header row

```
user_name, first_name, last_name, email, expiration_date, group
```

Only expiration_date is not required. If expiration_date is not provide the user's account will never expire (no lockout). The format for expiration date is ISO 8601. A valid example is ```2018-11-30T22:38:40.326Z```

A google service account is needed to download the sheet. See this [Google document](https://developers.google.com/identity/protocols/OAuth2ServiceAccount) for information about creating a service account

97 changes: 97 additions & 0 deletions roles/idm/lookup_plugins/csvtojson.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from ansible.errors import AnsibleError, AnsibleParserError
from ansible.plugins.lookup import LookupBase

import csv
import json

try:
from __main__ import display
except ImportError:
from ansible.utils.display import Display
display = Display()


class LookupModule(LookupBase):

def run(self, terms, variables=None, **kwargs):

ret = []

#Needed for Ansible 2.1.2.0
basedir = self.get_basedir(variables)

for term in terms:

params = term.split()

paramvals = {
'file' : 'users.csv',
'var' : 'users'
}

# parameters specified?
try:
for param in params:
name, value = param.split('=')
assert(name in paramvals)
paramvals[name] = value
display.vvvv(u"Param: %s : %s" % (name, value))
except (ValueError, AssertionError) as e:
raise AnsibleError(e)

display.debug("File lookup term: %s" % term)

# Find the file in the expected search path - version 2.1.2.0
lookupfile = self._loader.path_dwim_relative(basedir, 'files', paramvals['file'])

#Newer version of ansible uses this lookup -
#lookupfile = self.find_file_in_search_path(variables, 'files', term)

display.vvvv(u"File lookup using %s as file" % paramvals['file'])
try:
if lookupfile:
#read csv into rows
with open(lookupfile) as f:
reader = csv.DictReader(f)
rows = list(reader)

# do output for users or groups
if(paramvals['var'] == 'user_groups'):
ret.append(self.get_user_groups(rows))
else:
ret.append(self.get_users(rows))

else:
raise AnsibleParserError()
except AnsibleParserError:
raise AnsibleError("could not locate file in lookup: %s" % paramvals['file'])

return ret

# get json for users - file should already support this format
def get_users(self, rows):

display.vvvv(u"Getting users")

return json.dumps(rows)

# get json for groups - need to maniuplate the rows a bit.
# take username, group and transfrom to { name: mygroup, members: [ user_name: user1 }, { user_name: user2 } ]}
def get_user_groups(self, rows):

display.vvvv(u"Getting user groups")

userGroupsDict = {}

userGroupList = []

for row in rows:
if row['group'] not in userGroupsDict :
userGroupsDict[row['group']] = []

userGroupsDict[row['group']].append(row['user_name'])

for key in userGroupsDict :
userGroupList.append({ "name": key, "members": userGroupsDict[key]})

return json.dumps(userGroupList)
19 changes: 19 additions & 0 deletions roles/idm/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
# This test covers the full feature set provided by the role

- name: Download the Google Sheet
command: "{{ gdrive_command_tool }} --service-account {{ google_service_account }} export {{ google_doc_file_id }} --force"

- name: Convert csv to json - set facts
set_fact:
users: "{{ lookup('csvtojson', 'file=' + google_doc_file_name + ' var=users') }}"
user_groups: "{{ lookup('csvtojson', 'file=' + google_doc_file_name + ' var=user_groups') }}"

- name: Run role Create Identities
include_role:
name: ../ansible-stacks/roles/create-identities

- name: Clean up file
file:
path: "{{ google_doc_file_name }}"
state: absent

0 comments on commit 2a9df18

Please sign in to comment.