IBM Cloud Infrastructure(旧SoftLayer)ユーザー作成＆権限追加ツール

プロジェクトで各メンバーにIBM CloudのIDを作成する際にポータルで手作業で行うのは単調な割に手間のかかる作業です。slcliツールでもユーザーは作成可能ですが、権限の追加は個別に権限を追加する必要があり（試していないですが）これも手間がかかる作業です。

そこでユーザーを作成して、ポータルにあるSUPERUSER/BASIC/READONLYといったプリセットの権限を設定するツールを作成しました。

あくまでプリセットの権限のユーザーをクイックに作成することがこのツールの目的であり、個別のユーザーに細かく権限を設定する場合はこのツールは適していません。またユーザーの一覧表示や削除は従来のポータルやslcliツールが適しており、このツールではこれらの機能はないです。

## 使い方

実行にはsoftlayer-python (https://github.com/softlayer/softlayer-python) が必要でホームディレクトリの.softlayerにusernameとapi_keyを記述しておく必要があります。

python2でもpython3でも動作します。

```
$ python sl_user_create.py -h
usage: sl_user_create.py [-h] [-o ONLYPERMS] [-v]
                         username [email] [first] [last] [perms]

Create SoftLayer user and add permissions

positional arguments:
  username              unique user name
  email                 new user's mail address
  first                 new user's first name
  last                  new user's last address
  perms                 permission set
                        [NONE(default)/SUPERUSER/BASIC/READONLY]

optional arguments:
  -h, --help            show this help message and exit
  -o ONLYPERMS, --onlyperms ONLYPERMS
                        only add permissions to existing user
                        [NONE(default)/SUPERUSER/BASIC/READONLY]
  -v, --verbose         verbose mode
```

ユーザー作成は例えば'test-hogehoge3'ユーザーを作成する場合下記のように、メールアドレス、名前、プリセット権限の種類(SUPERUSER/BASIC/READONLY)と一緒に指定します。

```
$ python sl_user_create.py test-hogehoge3 hogehoge@nowhere.com Taro Hoge READONLY
creating a new user test-hogehoge3
adding READONLY permissions into test-hogehoge3
```
'-p'オプションで既存ユーザーに対してパーミッションの追加のみが可能です。

```
$ python sl_user_create.py -o READONLY test-hogehoge8
adding READONLY permissions into test-hogehoge8
```

パーミッションを取得するツールとしてsl_user_get_permissions.pyもあります。SUPERUSER/BASIC/READONLYのプリセットは2018年11月時点でポータルで設定して付与された権限を反映しています。プリセットの内容は将来変更になる可能性があります。

```
$ python sl_user_get_permissions.py test-hogehoge10
ACCESS_ALL_GUEST
TICKET_VIEW_BY_VIRTUAL_GUEST
ACCESS_ALL_DEDICATEDHOSTS
TICKET_VIEW
LICENSE_VIEW
TICKET_VIEW_BY_HARDWARE
ACCOUNT_SUMMARY_VIEW
ACCESS_ALL_HARDWARE
CDN_BANDWIDTH_VIEW
DEDICATED_HOST_VIEW
HARDWARE_VIEW
BANDWIDTH_MANAGE
TICKET_SEARCH
VIRTUAL_GUEST_VIEW
```

## ツールのコード
``` python:sl_user_create.py 
# -*- coding: utf-8 -*-

import SoftLayer, random, string, re, sys
from pprint import pprint

# declare permissions
readonly_permissions = ["ACCESS_ALL_GUEST", "TICKET_VIEW_BY_VIRTUAL_GUEST", "ACCESS_ALL_DEDICATEDHOSTS", "TICKET_VIEW", "LICENSE_VIEW", "TICKET_VIEW_BY_HARDWARE", "ACCOUNT_SUMMARY_VIEW", "ACCESS_ALL_HARDWARE", "CDN_BANDWIDTH_VIEW", "DEDICATED_HOST_VIEW", "HARDWARE_VIEW", "BANDWIDTH_MANAGE", "TICKET_SEARCH", "VIRTUAL_GUEST_VIEW", ]

basic_permissions = ["TICKET_EDIT", "ACCESS_ALL_GUEST", "USER_MANAGE", "TICKET_VIEW_BY_VIRTUAL_GUEST", "FIREWALL_RULE_MANAGE", "HOST_ID_MANAGE", "ACCESS_ALL_DEDICATEDHOSTS", "TICKET_VIEW", "LICENSE_VIEW", "TICKET_VIEW_BY_HARDWARE", "ACCOUNT_SUMMARY_VIEW", "ACCESS_ALL_HARDWARE", "PORT_CONTROL", "LOADBALANCER_MANAGE", "SOFTWARE_FIREWALL_MANAGE", "CDN_BANDWIDTH_VIEW", "DEDICATED_HOST_VIEW", "HARDWARE_VIEW", "BANDWIDTH_MANAGE", "TICKET_SEARCH", "DNS_MANAGE", "REMOTE_MANAGEMENT", "MONITORING_MANAGE", "VIRTUAL_GUEST_VIEW", "VULN_SCAN_MANAGE", "NTF_SUBSCRIBER_MANAGE", "FIREWALL_MANAGE", "NETWORK_MESSAGE_DELIVERY_MANAGE", "IP_ADD", "ANTI_MALWARE_MANAGE", ]

superuser_permissions = ["TICKET_EDIT", "CUSTOMER_POST_PROVISION_SCRIPT_MANAGEMENT", "ACCESS_ALL_GUEST", "REQUEST_COMPLIANCE_REPORT", "VIEW_URCHIN", "USER_MANAGE", "TICKET_VIEW_BY_VIRTUAL_GUEST", "TICKET_VIEW_ALL", "FIREWALL_RULE_MANAGE", "TICKET_ADD", "NETWORK_TUNNEL_MANAGE", "NAS_MANAGE", "HOST_ID_MANAGE", "HOSTNAME_EDIT", "VPN_MANAGE", "SECURITY_CERTIFICATE_MANAGE", "PUBLIC_NETWORK_COMPUTE", "ACCESS_ALL_DEDICATEDHOSTS", "TICKET_VIEW", "GATEWAY_MANAGE", "SERVER_UPGRADE", "LICENSE_VIEW", "CDN_FILE_MANAGE", "TICKET_VIEW_BY_HARDWARE", "USER_EVENT_LOG_VIEW", "DATACENTER_ROOM_ACCESS", "PUBLIC_IMAGE_MANAGE", "SAML_AUTHENTICATION_MANAGE", "SERVER_ADD", "SERVICE_ADD", "UPDATE_PAYMENT_DETAILS", "ONE_TIME_PAYMENTS", "ACCOUNT_SUMMARY_VIEW", "ACCESS_ALL_HARDWARE", "SERVER_CANCEL", "PORT_CONTROL", "LOADBALANCER_MANAGE", "SOFTWARE_FIREWALL_MANAGE", "CDN_BANDWIDTH_VIEW", "NETWORK_ROUTE_MANAGE", "DATACENTER_ACCESS", "CUSTOMER_SSH_KEY_MANAGEMENT", "VIEW_CPANEL", "ADD_SERVICE_STORAGE", "COMPANY_EDIT", "SERVICE_CANCEL", "NETWORK_VLAN_SPANNING", "DEDICATED_HOST_VIEW", "HARDWARE_VIEW", "CDN_ACCOUNT_MANAGE", "BANDWIDTH_MANAGE", "TICKET_SEARCH", "VIEW_CUSTOMER_SOFTWARE_PASSWORD", "SCALE_GROUP_MANAGE", "DNS_MANAGE", "REMOTE_MANAGEMENT", "MONITORING_MANAGE", "VIEW_QUANTASTOR", "INSTANCE_UPGRADE", "VIRTUAL_GUEST_VIEW", "CUSTOMER_PLACEMENT_GROUP_MANAGEMENT", "SECURITY_CERTIFICATE_VIEW", "VIEW_HELM", "SERVICE_UPGRADE", "VULN_SCAN_MANAGE", "NTF_SUBSCRIBER_MANAGE", "FIREWALL_MANAGE", "SERVER_RELOAD", "NETWORK_MESSAGE_DELIVERY_MANAGE", "MANAGE_SECURITY_GROUPS", "IP_ADD", "ANTI_MALWARE_MANAGE", "LOCKBOX_MANAGE", "VIEW_PLESK", "EU_LIMITED_PROCESSING_MANAGE", "CUSTOMER_RESERVED_CAPACITY_GROUP_MANAGEMENT", ]

# check args
import argparse
parser = argparse.ArgumentParser(description="Create SoftLayer user and add permissions")

parser.add_argument('username', help="unique user name")
parser.add_argument('email', help="new user's mail address", nargs='?', default="NONE")
parser.add_argument('first', help="new user's first name", nargs='?', default="NONE")
parser.add_argument('last', help="new user's last address", nargs='?', default="NONE")
parser.add_argument('perms', help="permission set [NONE(default)/SUPERUSER/BASIC/READONLY]", nargs='?', default="NONE")
parser.add_argument('-o', '--onlyperms', help="only add permissions to existing user [NONE(default)/SUPERUSER/BASIC/READONLY]")
parser.add_argument('-v', '--verbose', help="verbose mode", action="store_true")

args = parser.parse_args()

# check username
if(len(re.findall('[A-Z]', args.username))>0):
    print("username must be lower case")
    sys.exit()

# initialize client
client = SoftLayer.create_client_from_env(config_file='~/.softlayer')
if(args.verbose):
    print("using usename[" + client.auth.username + "] for API call")

# Get Account Info
account = client.call('Account', 'getObject')

user_template = {
    'username': args.username,
    'firstName': args.first,
    'lastName': args.last,
    'email': args.email,
    'companyName': account['companyName'],
    'address1': account['address1'],
    'city': account['city'],
    'country': account['country'],
    'state': account['state'],
    'postalCode': account['postalCode'],
    'userStatusId': 1001,
    'timezoneId': 158,
    'localeId': 1,
    'sslVpnAllowedFlag': True
}

# generate tmppass
passwdcond = False
specialchars='_-|@.,?/!~#$%^&*(){}[]=.'

while(passwdcond == False):
    tmppass =''.join([random.choice(specialchars + string.ascii_letters + string.digits) for i in range(8)])
    lcount = len(re.findall('[a-z]', tmppass))
    ucount = len(re.findall('[A-Z]', tmppass))
    numcount = len(re.findall('\d', tmppass))
    specialcharcount = len(re.findall('[\_\-\|\@\.\,\?\/\!\~\#\$\%\^\&\*\(\)\{\}\[\]\=\.]', tmppass))
    if(lcount > 0 and ucount > 0 and numcount > 0 and specialcharcount > 0):
        passwdcond = True

# create user
if(args.onlyperms == None):
    print('creating a new user ' +  args.username)
    new_user = client['User_Customer'].createObject(user_template, tmppass, tmppass)


if(args.onlyperms != None):
    args.perms = args.onlyperms
    
if(args.perms == "SUPERUSER" or args.perms == "BASIC" or args.perms == "READONLY"):
    # get target user
    users = client.call('Account', 'getUsers')
    for u in users:
        if u['username'] == args.username:
            print("adding " + args.perms + " permissions into " + u['username'])
            # Add User Permissions
            permissions_array = eval(args.perms.lower() + '_permissions')
            permissions_array_forapi = list(map(lambda x: {'keyName': x}, permissions_array))
            client.call('User_Customer', 'addBulkPortalPermission', permissions_array_forapi, id=u['id'])
elif(args.perms == "NONE"):
    pass
else:
    print("Unknow Permission: " + args.permissions)
```

``` python:sl_user_get_permissions.py
# -*- coding: utf-8 -*-

import SoftLayer, random, string
from pprint import pprint

# check args
import argparse
parser = argparse.ArgumentParser(description="Create SoftLayer user and add permissions")

parser.add_argument('username', help="unique user name")
parser.add_argument('-v', '--verborse', help="verbose mode", action="store_true")
parser.add_argument('-p', '--pythoncode', help="generate python code", action="store_true")

args = parser.parse_args()

# initialize client
client = SoftLayer.create_client_from_env(config_file='~/.softlayer')

# get target user
users = client.call('Account', 'getUsers')
for u in users:
    if u['username'] == args.username:
        # Add User Permissions
        perms = client.call('User_Customer', 'getPermissions', id=u['id'])
        permstrs = list(map(lambda x: x['keyName'], perms))
        if(args.pythoncode == True):
            sys.stdout.write("[")
        for i in permstrs:
            if(args.pythoncode):
                sys.stdout.write('"' + i + '", ')
            else:
                print(i)
        if(args.pythoncode == True):
            print("]")