├── src ├── requirements.txt ├── iamport.py ├── aws.py └── file_helper.py ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── Readme.md └── .gitignore /src/requirements.txt: -------------------------------------------------------------------------------- 1 | toml==0.10.1 2 | -------------------------------------------------------------------------------- /src/iamport.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import aws 3 | 4 | parser = argparse.ArgumentParser() 5 | 6 | parser.add_argument("--provider", default=True) 7 | 8 | args = parser.parse_args() 9 | 10 | if args.provider == "aws": 11 | aws.iamport() 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /src/aws.py: -------------------------------------------------------------------------------- 1 | import toml 2 | import ntpath 3 | 4 | import file_helper as fh 5 | 6 | def iamport(): 7 | # Get OS-aware downloads folder 8 | DOWNLOADS_FOLDER = fh.get_download_path() 9 | 10 | # assumed that the latest downloaded file is the aws profile as csv 11 | profile_csv = fh.get_newest_csv(DOWNLOADS_FOLDER) 12 | 13 | # Get filename that'll be used as IAM profile name 14 | profile_name = ntpath.basename(profile_csv).replace(".csv", "") 15 | 16 | # Get aws credentials file from home directory 17 | aws_credentials_file = fh.get_aws_credentials() 18 | 19 | # Init reader for csv file as OrderedDict 20 | reader = fh.csv_to_ordered_dict(profile_csv) 21 | 22 | for line in reader: 23 | profile_dict = dict(line) 24 | 25 | # Clean up the new profile as aws configuration expected format 26 | profile_dict = {profile_name: profile_dict} 27 | profile = toml.dumps(profile_dict).replace('"', "") 28 | profile = fh.replace_profile_keys(profile) 29 | 30 | # Append new profile to actual aws config 31 | with open(aws_credentials_file, "a+") as aws_file: 32 | aws_file.writelines("\n" + profile) 33 | aws_file.close() 34 | 35 | print("Imported profile:") 36 | print(profile) 37 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Import with iamport 2 | [![forthebadge made-with-python](http://ForTheBadge.com/images/badges/made-with-python.svg)](https://www.python.org/) 3 | [![GitHub license](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/Naereen/StrapDown.js/blob/master/LICENSE) 4 | 5 | 6 | **iamport** works no matter your operating system is; Import your external configurations and credentials without extra manual work. It has been built to import AWS IAM configuration by latest downloaded CSV file but should and will be cloud agnostic. 7 | 8 | # Installation 9 | 10 | git clone https://github.com/ugurcemozturk/iamport 11 | pip install -r requirements.txt 12 | 13 | 14 | # Usage 15 | 16 | Simply import your new IAM user credentials from **the latest downloaded CSV** to AWS config file, assumed at home folder, **~/.aws/credentials** 17 | 18 | 19 | iamport --provider aws 20 | 21 | # TO-DO 22 | 23 | - [ ] Add Azure 24 | - [ ] Add GCP 25 | - [ ] Override csv path by parameter 26 | - [ ] Override .aws config path by parameter 27 | - [ ] Option for file writing, just print to console 28 | 29 | ## Flow 30 | 31 | ```mermaid 32 | sequenceDiagram 33 | Iamport ->> OS: Gimme /Downloads path 34 | OS->>Iamport: It's ~/Downloads(i.e.) 35 | Iamport-> Downloads: Gimme latest .csv file 36 | Downloads->> Iamport: Here is the config file: 'iam-profile-name.csv' 37 | Iamport->> AWS Config: Convert csv to TOML and save to ~/.aws/credentials (i.e.) 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /src/file_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import csv 3 | 4 | def get_newest_csv(path): 5 | """Get latest CSV from given path""" 6 | files = os.listdir(path) 7 | paths = [ 8 | os.path.join(path, basename) for basename in files if basename.endswith(".csv") 9 | ] 10 | return max(paths, key=os.path.getctime) 11 | 12 | 13 | def get_home_dir(): 14 | """Returns OS user home directory""" 15 | return os.path.expanduser("~") 16 | 17 | def get_aws_credentials(): 18 | """Returns aws credentials file""" 19 | return os.path.join(get_home_dir(),".aws","credentials") 20 | 21 | 22 | def get_download_path(): 23 | """Returns the default downloads path for linux or windows""" 24 | if os.name == "nt": 25 | import winreg 26 | sub_key = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" 27 | downloads_guid = "{374DE290-123F-4565-9164-39C4925E467B}" 28 | with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key: 29 | location = winreg.QueryValueEx(key, downloads_guid)[0] 30 | return location 31 | else: 32 | return os.path.join(get_home_dir(), "Downloads") 33 | 34 | 35 | def csv_to_ordered_dict(_csv): 36 | """Returns an OrderedDict from CSV""" 37 | return csv.DictReader(open(_csv)) 38 | 39 | 40 | def replace_profile_keys(profile): 41 | """Replace CSV keys with aws iam config formatted keys""" 42 | profile = profile.replace("Access key ID", "aws_access_key_id") 43 | profile = profile.replace("Secret access key", "aws_secret_access_key") 44 | return profile 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editors 2 | .vscode/ 3 | .idea/ 4 | 5 | # Vagrant 6 | .vagrant/ 7 | 8 | # Mac/OSX 9 | .DS_Store 10 | 11 | # Windows 12 | Thumbs.db 13 | 14 | # Source for the following rules: https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore 15 | # Byte-compiled / optimized / DLL files 16 | __pycache__/ 17 | *.py[cod] 18 | *$py.class 19 | 20 | # C extensions 21 | *.so 22 | 23 | # Distribution / packaging 24 | .Python 25 | build/ 26 | develop-eggs/ 27 | dist/ 28 | downloads/ 29 | eggs/ 30 | .eggs/ 31 | lib/ 32 | lib64/ 33 | parts/ 34 | sdist/ 35 | var/ 36 | wheels/ 37 | *.egg-info/ 38 | .installed.cfg 39 | *.egg 40 | MANIFEST 41 | 42 | # PyInstaller 43 | # Usually these files are written by a python script from a template 44 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 45 | *.manifest 46 | *.spec 47 | 48 | # Installer logs 49 | pip-log.txt 50 | pip-delete-this-directory.txt 51 | 52 | # Unit test / coverage reports 53 | htmlcov/ 54 | .tox/ 55 | .nox/ 56 | .coverage 57 | .coverage.* 58 | .cache 59 | nosetests.xml 60 | coverage.xml 61 | *.cover 62 | .hypothesis/ 63 | .pytest_cache/ 64 | 65 | # Translations 66 | *.mo 67 | *.pot 68 | 69 | # Django stuff: 70 | *.log 71 | local_settings.py 72 | db.sqlite3 73 | 74 | # Flask stuff: 75 | instance/ 76 | .webassets-cache 77 | 78 | # Scrapy stuff: 79 | .scrapy 80 | 81 | # Sphinx documentation 82 | docs/_build/ 83 | 84 | # PyBuilder 85 | target/ 86 | 87 | # Jupyter Notebook 88 | .ipynb_checkpoints 89 | 90 | # IPython 91 | profile_default/ 92 | ipython_config.py 93 | 94 | # pyenv 95 | .python-version 96 | 97 | # celery beat schedule file 98 | celerybeat-schedule 99 | 100 | # SageMath parsed files 101 | *.sage.py 102 | 103 | # Environments 104 | .env 105 | .venv 106 | env/ 107 | venv/ 108 | ENV/ 109 | env.bak/ 110 | venv.bak/ 111 | 112 | # Spyder project settings 113 | .spyderproject 114 | .spyproject 115 | 116 | # Rope project settings 117 | .ropeproject 118 | 119 | # mkdocs documentation 120 | /site 121 | 122 | # mypy 123 | .mypy_cache/ 124 | .dmypy.json 125 | dmypy.json 126 | 127 | eksport/ --------------------------------------------------------------------------------