;;; aws.el --- Some shortcuts for working with AWS -*- lexical-binding: t -*- ;; This file is not part of GNU Emacs ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; commentary ;;; Code: (defcustom aws-cli-auth-provider "saml2aws" "The command that provides AWS authentication." :type 'string :group 'aws :group 'theurgy) (defcustom aws-roles '() "List of strings of each possible AWS role completion for `aws-sign-in'." :type '(repeat string) :group 'aws :group 'theurgy) (defcustom aws-auto-reauth nil "If nil, do not reauth. Otherwise it should be a number, the number of minutes on the reauth timer." :type 'integer :group 'aws :group 'theurgy) (defvar aws-reauth-timer nil "The reauth timer, if created.") (defvar aws-post-signin-hook nil "Hook to run after an AWS sign-in.") (defun aws--login (role) "Internal login function --- handles the command as a process, and prompts for MFA." (let* ((process-name (format "%s-%s" aws-cli-auth-provider (replace-regexp-in-string "[/:]" "-" role))) (buffer (get-buffer-create (format "*%s*" process-name))) (prompt-regexp (rx (or "Enter verification code"))) (prompt-sent nil)) (with-current-buffer buffer (erase-buffer)) (make-process :name process-name :buffer buffer :command (list aws-cli-auth-provider "login" "--force" "--skip-prompt" "--role" role) :filter (lambda (proc output) (with-current-buffer (process-buffer proc) (goto-char (point-max)) (insert output) (unless prompt-sent (let ((buffer-contents (buffer-string))) (when (string-match-p prompt-regexp buffer-contents) (setq prompt-sent t) (let ((token (read-passwd "MFA token: "))) (process-send-string proc (concat token "\n")))))))) :sentinel (lambda (proc event) (when (string= "finished\n" event) (run-hooks 'aws-post-signin-hook)))))) (defun aws-sign-in () "Sign in with AWS." (interactive) (let* ((role (completing-read "AWS Role: " aws-roles)) (auth-fn (lambda () (message (concat "Authenticating with " role " via " aws-cli-auth-provider)) (aws--login role)))) (funcall auth-fn) (when aws-auto-reauth (when aws-reauth-timer (cancel-timer aws-reauth-timer)) (setq aws-reauth-timer (run-at-time 0 (* 60 aws-auto-reauth) auth-fn))))) ;; Utility wrappers for the AWS CLI (defun aws-delete-appconfig-app (application-id) "Delete an AWS appconfig app and all dependencies, by its `APPLICATION-ID'." (interactive "sApplication ID: ") (let ((profiles (mapcar (lambda (line) (nth 2 (string-split line))) (remove "" (string-split (shell-command-to-string (format "aws appconfig list-configuration-profiles --application-id %s" application-id)) "\n")))) (environments (mapcar (lambda (line) (nth 2 (string-split line))) (remove "" (string-split (shell-command-to-string (format "aws appconfig list-environments --application-id %s" application-id)) "\n")))) (output-buffer (get-buffer-create (format "*aws-delete-app-%s*" application-id)))) (dolist (p profiles) (let ((version-max (string-to-number (car (last (string-split (car (string-split (shell-command-to-string (format "aws appconfig list-hosted-configuration-versions --application-id %s --configuration-profile-id %s" application-id p)) "\n")))))))) (dolist (v (number-sequence 1 version-max)) (shell-command (format "aws appconfig delete-hosted-configuration-version --application-id %s --configuration-profile-id %s --version-number %s" application-id p v) output-buffer)) (shell-command (format "aws appconfig delete-configuration-profile --application-id %s --configuration-profile-id %s" application-id p) output-buffer))) (dolist (e environments) (shell-command (format "aws appconfig delete-environment --application-id %s --environment-id %s" application-id e) output-buffer)) (shell-command (format "aws appconfig delete-application --application-id %s" application-id) output-buffer) (message (format "Deleted application %s" application-id)))) (provide 'aws) ;;; aws.el ends here