Browse code
feat: fetch resources, add statuses
Ed Langley authored on 29/10/2020 21:59:19
Showing 8 changed files
Showing 8 changed files
- .gitignore
- aws-result.lisp
- build.lisp
- cli.lisp
- clone-all-the-things.sh
- daydreamer.asd
- main.lisp
- make.sh
... | ... |
@@ -1,32 +1,43 @@ |
1 | 1 |
(defpackage :daydreamer.aws-result |
2 |
- (:use :cl :fw.lu :alexandria :st) |
|
3 |
- (:export |
|
4 |
- #:stack |
|
5 |
- #:outputs |
|
6 |
- #:reader |
|
7 |
- #:creation-time |
|
8 |
- #:notification-arns |
|
9 |
- #:stack-id |
|
10 |
- #:stack-name |
|
11 |
- #:description |
|
12 |
- #:stack-status |
|
13 |
- #:disable-rollback |
|
14 |
- #:tags |
|
15 |
- #:deletion-time |
|
16 |
- #:rollback-configuration |
|
17 |
- #:drift-information |
|
18 |
- #:enable-termination-protection |
|
19 |
- #:parameters |
|
20 |
- #:start-date-time |
|
21 |
- #:end-date-time |
|
22 |
- #:creation-date-time |
|
23 |
- #:extract-timeline |
|
24 |
- #:extract-list |
|
25 |
- #:extract-stack |
|
26 |
- #:timeline |
|
27 |
- #:tagged-kv-formatter)) |
|
2 |
+ (:use :cl :fw.lu :alexandria) |
|
3 |
+ (:export #:stack |
|
4 |
+ #:outputs |
|
5 |
+ #:reader |
|
6 |
+ #:creation-time |
|
7 |
+ #:notification-arns |
|
8 |
+ #:stack-id |
|
9 |
+ #:stack-name |
|
10 |
+ #:description |
|
11 |
+ #:stack-status |
|
12 |
+ #:disable-rollback |
|
13 |
+ #:tags |
|
14 |
+ #:deletion-time |
|
15 |
+ #:rollback-configuration |
|
16 |
+ #:drift-information |
|
17 |
+ #:enable-termination-protection |
|
18 |
+ #:parameters |
|
19 |
+ #:start-date-time |
|
20 |
+ #:end-date-time |
|
21 |
+ #:creation-date-time |
|
22 |
+ #:extract-timeline |
|
23 |
+ #:extract-list |
|
24 |
+ #:extract-stack |
|
25 |
+ #:timeline |
|
26 |
+ #:tagged-kv-formatter |
|
27 |
+ #:extract-stack-resource |
|
28 |
+ #:stack-resource |
|
29 |
+ #:physical-resource-id |
|
30 |
+ #:resource-status |
|
31 |
+ #:logical-resource-id |
|
32 |
+ #:timestamp |
|
33 |
+ #:resource-type |
|
34 |
+ #:resource-status-reason)) |
|
28 | 35 |
(in-package :daydreamer.aws-result) |
29 | 36 |
|
37 |
+(defgeneric stack-name (stack) |
|
38 |
+ (:method ((stack string)) |
|
39 |
+ stack)) |
|
40 |
+ |
|
30 | 41 |
(defun find-all-indices (pred str &optional accum (start (or (car accum) 0))) |
31 | 42 |
(check-type pred function) |
32 | 43 |
(check-type str string) |
... | ... |
@@ -158,16 +169,18 @@ |
158 | 169 |
(defparameter *stack-statuses* |
159 | 170 |
'("CREATE_COMPLETE" "CREATE_IN_PROGRESS" "CREATE_FAILED" |
160 | 171 |
"DELETE_COMPLETE" "DELETE_FAILED" "DELETE_IN_PROGRESS" |
161 |
- "REVIEW_IN_PROGRESS" |
|
162 |
- "ROLLBACK_COMPLETE" "ROLLBACK_FAILED" "ROLLBACK_IN_PROGRESS" |
|
163 |
- "UPDATE_COMPLETE" "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS" "UPDATE_IN_PROGRESS" |
|
164 |
- "UPDATE_ROLLBACK_COMPLETE" "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS" "UPDATE_ROLLBACK_FAILED" "UPDATE_ROLLBACK_IN_PROGRESS")) |
|
172 |
+ "REVIEW_IN_PROGRESS" "ROLLBACK_COMPLETE" "ROLLBACK_FAILED" |
|
173 |
+ "ROLLBACK_IN_PROGRESS" "UPDATE_COMPLETE" |
|
174 |
+ "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS" "UPDATE_IN_PROGRESS" |
|
175 |
+ "UPDATE_ROLLBACK_COMPLETE" |
|
176 |
+ "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS" |
|
177 |
+ "UPDATE_ROLLBACK_FAILED" "UPDATE_ROLLBACK_IN_PROGRESS")) |
|
165 | 178 |
|
166 | 179 |
#+nil |
167 |
-(aws-sdk/services/cloudformation:list-stacks |
|
180 |
+(aws-sdk/services/cloudformation:list-stacks |
|
168 | 181 |
:stack-status-filter '("UPDATE_COMPLETE" "UPDATE_IN_PROGRESS" |
169 | 182 |
"UPDATE_COMPLETE_CLEANUP_IN_PROGRESS" "UPDATE_ROLLBACK_COMPLETE" |
170 |
- "UPDATE_ROLLBACK_IN_PROGRESS" "UPDATE_ROLLBACK_FAILED" |
|
183 |
+ "UPDATE_ROLLBACK_IN_PROGRESS" "UPDATE_ROLLBACK_FAILED" |
|
171 | 184 |
"UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS" "CREATE_FAILED" |
172 | 185 |
"CREATE_COMPLETE" "CREATE_IN_PROGRESS")) |
173 | 186 |
|
... | ... |
@@ -183,11 +196,47 @@ |
183 | 196 |
s-edt (initialize-date s-edt) |
184 | 197 |
s-cdt (initialize-date s-cdt)))) |
185 | 198 |
|
186 |
- |
|
199 |
+(defclass stack-resource () |
|
200 |
+ ((%physical-resource-id :initarg :physical-resource-id :reader physical-resource-id) |
|
201 |
+ (%resource-status :initarg :resource-status :reader resource-status) |
|
202 |
+ (%resource-status-reason :initarg :resource-status-reason :reader resource-status-reason :initform nil) |
|
203 |
+ (%stack-id :initarg :stack-id :reader stack-id) |
|
204 |
+ (%stack-name :initarg :stack-name :reader stack-name) |
|
205 |
+ (%drift-information :initarg :drift-information :reader drift-information) |
|
206 |
+ (%logical-resource-id :initarg :logical-resource-id :reader logical-resource-id) |
|
207 |
+ (%timestamp :initarg :timestamp :reader timestamp) |
|
208 |
+ (%resource-type :initarg :resource-type :reader resource-type))) |
|
209 |
+ |
|
210 |
+(defmethod print-object ((o stack-resource) s) |
|
211 |
+ (print-unreadable-object (o s :type t :identity t) |
|
212 |
+ (format s "~a (~a): ~a" |
|
213 |
+ (logical-resource-id o) |
|
214 |
+ (resource-type o) |
|
215 |
+ (resource-status o)))) |
|
216 |
+ |
|
217 |
+(defun extract-stack-resource (it) |
|
218 |
+ (apply 'make-instance 'daydreamer.aws-result::stack-resource |
|
219 |
+ (daydreamer.aws-result::alist-to-initargs |
|
220 |
+ it (fw.lu:alist-string-hash-table |
|
221 |
+ `((:physical-resource-id . car) |
|
222 |
+ (:resource-status . car) |
|
223 |
+ (:resource-status-reason . car) |
|
224 |
+ (:stack-id . car) |
|
225 |
+ (:stack-name . car) |
|
226 |
+ (:drift-information . car) |
|
227 |
+ (:logical-resource-id . car) |
|
228 |
+ (:timestamp . car) |
|
229 |
+ (:resource-type . car)))))) |
|
230 |
+ |
|
231 |
+(defclass stack-template () |
|
232 |
+ ((template-body :initarg :template-body :reader template-body) |
|
233 |
+ (stages-available :initarg :stages-available :reader stages-available))) |
|
234 |
+ |
|
235 |
+ |
|
236 |
+#+(or) |
|
187 | 237 |
(deftest decamelize () |
188 | 238 |
(should be equal "a" (decamelize "A")) |
189 | 239 |
(should be equal "a" (decamelize "a")) |
190 | 240 |
(should be equal "outputs" (decamelize "Outputs")) |
191 | 241 |
(should be equal "outputs-outputs" (decamelize "OutputsOutputs")) |
192 | 242 |
(should be equal "a-b-c" (decamelize "ABC"))) |
193 |
- |
... | ... |
@@ -21,23 +21,25 @@ |
21 | 21 |
;; nil) |
22 | 22 |
|
23 | 23 |
(stepwise |
24 |
- ((defun load-compile (pn) |
|
25 |
- (load (compile-file pn)))) |
|
26 |
- |
|
27 |
- ((ql:quickload :cffi-grovel)) |
|
28 |
- ((princ |
|
29 |
- (mapcar 'load-compile |
|
30 |
- (remove #\. |
|
31 |
- (directory (merge-pathnames "*.asd" |
|
32 |
- *load-pathname*)) |
|
33 |
- :key 'pathname-name |
|
34 |
- :test 'alexandria:starts-with))) |
|
35 |
- (terpri)) |
|
36 |
- |
|
37 |
- ((ql:quickload :daydreamer)) |
|
38 |
- |
|
39 |
- ((asdf:operate :static-program-op :daydreamer)) |
|
40 |
- #+nil |
|
41 |
- ((asdf/driver:symbol-call :daydreamer.cli :dump)) |
|
42 |
- |
|
43 |
- ((sb-ext:quit))) |
|
24 |
+ ((defun load-compile (pn) |
|
25 |
+ (load (compile-file pn)))) |
|
26 |
+ |
|
27 |
+ ((ql:quickload :cffi-grovel)) |
|
28 |
+ ((princ |
|
29 |
+ (mapcar 'load-compile |
|
30 |
+ (remove #\. |
|
31 |
+ (directory (merge-pathnames "*.asd" |
|
32 |
+ *load-pathname*)) |
|
33 |
+ :key 'pathname-name |
|
34 |
+ :test 'alexandria:starts-with))) |
|
35 |
+ (terpri)) |
|
36 |
+ |
|
37 |
+ ((ql:quickload :daydreamer)) |
|
38 |
+ |
|
39 |
+ #+linux |
|
40 |
+ ((asdf:operate :static-program-op :daydreamer)) |
|
41 |
+ |
|
42 |
+ #-linux |
|
43 |
+ ((uiop:symbol-call :daydreamer.cli :dump)) |
|
44 |
+ |
|
45 |
+ ((sb-ext:quit))) |
... | ... |
@@ -13,30 +13,45 @@ |
13 | 13 |
|
14 | 14 |
(in-package :daydreamer.cli) |
15 | 15 |
|
16 |
- |
|
17 | 16 |
(defparameter *daydreamer-synopsis* |
18 | 17 |
(defsynopsis (:postfix "ARGS...") |
19 | 18 |
(group (:header "actions") |
20 |
- (flag :short-name "s" :long-name "stacks" :description "show stack information") |
|
21 |
- (flag :short-name "p" :long-name "parameters" :description "show stack parameters") |
|
22 |
- (flag :short-name "o" :long-name "outputs" :description "show stack outputs") |
|
23 |
- (flag :short-name "w" :long-name "watch" :description "watch a cloudformation stack until it's done processing") |
|
24 |
- (flag :short-name "i" :long-name "info" :description "get parameters, status and output of a stack") |
|
25 |
- #+null |
|
26 |
- (flag :short-name "s" :long-name "start") |
|
27 |
- (stropt :long-name "aws-region" :default-value "us-west-2") |
|
28 |
- (flag :short-name "u" :long-name "update")) |
|
19 |
+ (flag :short-name "s" :long-name "stacks" :description "show stack information") |
|
20 |
+ (flag :short-name "p" :long-name "parameters" :description "show stack parameters") |
|
21 |
+ (flag :short-name "o" :long-name "outputs" :description "show stack outputs") |
|
22 |
+ (flag :short-name "r" :long-name "resources" :description "show stack resources") |
|
23 |
+ (flag :short-name "w" :long-name "watch" :description "watch a cloudformation stack until it's done processing") |
|
24 |
+ (flag :short-name "i" :long-name "info" :description "get parameters, status and output of a stack") |
|
25 |
+ #+null |
|
26 |
+ (flag :short-name "s" :long-name "start") |
|
27 |
+ (stropt :long-name "aws-region" |
|
28 |
+ :description "explicitly pick AWS Region" |
|
29 |
+ :env-var "AWS_DEFAULT_REGION") |
|
30 |
+ (stropt :long-name "aws-profile" |
|
31 |
+ :description "aws profile to use for authentication" |
|
32 |
+ :env-var "AWS_PROFILE") |
|
33 |
+ (stropt :long-name "aws-access-key-id" |
|
34 |
+ :description "aws access-key-id to use for authentication" |
|
35 |
+ :env-var "AWS_ACCESS_KEY_ID") |
|
36 |
+ (stropt :long-name "aws-secret-access-key" |
|
37 |
+ :description "aws secret-access-key to use for authentication" |
|
38 |
+ :env-var "AWS_SECRET_ACCESS_KEY") |
|
39 |
+ (stropt :long-name "aws-session-token" |
|
40 |
+ :description "aws session-token to use for authentication" |
|
41 |
+ :env-var "AWS_SESSION_TOKEN") |
|
42 |
+ #+null |
|
43 |
+ (flag :short-name "u" :long-name "update")) |
|
29 | 44 |
(group (:header "misc") |
30 |
- (flag :long-name "rebuild") |
|
31 |
- (flag :long-name "self-test") |
|
32 |
- (flag :long-name "help")))) |
|
45 |
+ (flag :long-name "rebuild") |
|
46 |
+ (flag :long-name "self-test") |
|
47 |
+ (flag :long-name "help")))) |
|
33 | 48 |
|
34 | 49 |
(defun stacks-main () |
35 | 50 |
(mapcar (lambda (s) |
36 | 51 |
(format t "~3&STACK ~a ~a~2%" |
37 | 52 |
(daydreamer.aws-result:stack-name s) |
38 | 53 |
(daydreamer.aws-result:stack-status s)) |
39 |
- (stack-info s)) |
|
54 |
+ (stack-info s t t t)) |
|
40 | 55 |
(mapcar 'daydreamer.aws-result:extract-stack |
41 | 56 |
(daydreamer.aws-result:extract-list |
42 | 57 |
(cdar |
... | ... |
@@ -48,8 +63,8 @@ |
48 | 63 |
(defun stack-outputs-main (name) |
49 | 64 |
(stack-outputs (stack-for-name name))) |
50 | 65 |
|
51 |
-(defun stack-info-main (name) |
|
52 |
- (stack-info (stack-for-name name))) |
|
66 |
+(defun stack-info-main (name status parameters outputs resources) |
|
67 |
+ (stack-info (stack-for-name name) status parameters outputs resources)) |
|
53 | 68 |
|
54 | 69 |
(defun run-tests () |
55 | 70 |
(st:test :package (find-package :daydreamer.aws-result)) |
... | ... |
@@ -74,20 +89,58 @@ |
74 | 89 |
(let* ((context (net.didierverna.clon:make-context :synopsis *daydreamer-synopsis*)) |
75 | 90 |
(files (clon:remainder :context context)) |
76 | 91 |
(region (clon:getopt :long-name "aws-region")) |
77 |
- (aws-sdk:*session* (aws-sdk:make-session :credentials (aws-sdk:default-aws-credentials) |
|
78 |
- :region region))) |
|
92 |
+ (profile (clon:getopt :long-name "aws-profile")) |
|
93 |
+ (access-key-id (clon:getopt :long-name "aws-access-key-id")) |
|
94 |
+ (secret-access-key (clon:getopt :long-name "aws-secret-access-key")) |
|
95 |
+ (session-token (clon:getopt :long-name "aws-session-token"))) |
|
96 |
+ |
|
97 |
+ (cond (access-key-id |
|
98 |
+ (setf aws:*session* |
|
99 |
+ (aws:make-session |
|
100 |
+ :credentials (if session-token |
|
101 |
+ (aws:make-credentials |
|
102 |
+ :access-key-id access-key-id |
|
103 |
+ :secret-access-key secret-access-key |
|
104 |
+ :session-token session-token |
|
105 |
+ ) |
|
106 |
+ (aws:make-credentials |
|
107 |
+ :access-key-id access-key-id |
|
108 |
+ :secret-access-key secret-access-key |
|
109 |
+ :session-token nil |
|
110 |
+ )) |
|
111 |
+ :region region))) |
|
112 |
+ ((and region profile) |
|
113 |
+ (aws:init-session |
|
114 |
+ :region region |
|
115 |
+ :profile profile)) |
|
116 |
+ (region |
|
117 |
+ (aws:init-session |
|
118 |
+ :region region)) |
|
119 |
+ (profile |
|
120 |
+ (aws:init-session |
|
121 |
+ :profile profile)) |
|
122 |
+ (t |
|
123 |
+ (aws:init-session))) |
|
79 | 124 |
|
80 |
- (format *error-output* "~&IN REGION: ~a~%" region) |
|
125 |
+ (format *error-output* "~&IN REGION: ~a~%WITH PROFILE: ~a~%" |
|
126 |
+ (aws:session-region aws:*session*) |
|
127 |
+ profile) |
|
81 | 128 |
|
82 | 129 |
(cond ((clon:getopt :long-name "help") (clon:help)) |
83 |
- ((clon:getopt :long-name "info") (stack-info-main (car files))) |
|
84 | 130 |
((clon:getopt :long-name "watch") (daydreamer.main:watch-stack (car files))) |
85 | 131 |
((clon:getopt :long-name "stacks") (stacks-main)) |
86 |
- ((clon:getopt :long-name "outputs") (stack-outputs-main (car files))) |
|
87 |
- ((clon:getopt :long-name "parameters") (stack-parameters-main (car files))) |
|
88 | 132 |
((clon:getopt :long-name "self-test") (run-tests)) |
89 | 133 |
((clon:getopt :long-name "rebuild") |
90 | 134 |
(load (compile-file (load-time-value |
91 | 135 |
(asdf:system-relative-pathname :daydreamer "cli.lisp")))) |
92 |
- (dump))))) |
|
93 |
- |
|
136 |
+ (dump)) |
|
137 |
+ (t |
|
138 |
+ (let ((info (clon:getopt :long-name "info")) |
|
139 |
+ (parameters (clon:getopt :long-name "parameters")) |
|
140 |
+ (outputs (clon:getopt :long-name "outputs")) |
|
141 |
+ (resources (clon:getopt :long-name "resources"))) |
|
142 |
+ (stack-info-main (car files) |
|
143 |
+ info |
|
144 |
+ (or info parameters) |
|
145 |
+ (or info outputs) |
|
146 |
+ resources)))))) |
... | ... |
@@ -1,12 +1,20 @@ |
1 | 1 |
#!/usr/bin/env bash |
2 |
-cd $HOME |
|
2 |
+ |
|
3 |
+set -eu -o pipefail |
|
4 |
+ |
|
5 |
+cd "$HOME" |
|
3 | 6 |
|
4 | 7 |
pwd |
5 |
-git clone --depth=1 https://gitlab.com/fiddlerwoaroof/osicat.git ~/quicklisp/local-projects/osicat |
|
6 |
-git clone --depth=1 https://gitlab.com/fiddlerwoaroof/cffi.git ~/quicklisp/local-projects/cffi |
|
7 | 8 |
|
8 |
-git clone --depth=1 https://github.com/fiddlerwoaroof/fwoar.lisputils.git ~/quicklisp/local-projects/fwoar.lisputils/ |
|
9 |
-git clone --depth=1 https://github.com/fiddlerwoaroof/data-lens.git ~/quicklisp/local-projects/data-lens/ |
|
10 |
-git clone --depth=1 https://github.com/pokepay/aws-sdk-lisp.git ~/quicklisp/local-projects/aws-sdk-lisp && pushd ~/quicklisp/local-projects/aws-sdk-lisp && git checkout 6d1f66e && popd |
|
9 |
+git clone --depth=1 https://gitlab.com/fiddlerwoaroof/osicat.git "$HOME"/quicklisp/local-projects/osicat |
|
10 |
+git clone --depth=1 https://gitlab.com/fiddlerwoaroof/cffi.git "$HOME"/quicklisp/local-projects/cffi |
|
11 |
+ |
|
12 |
+git clone --depth=1 https://github.com/fiddlerwoaroof/fwoar.lisputils.git "$HOME"/quicklisp/local-projects/fwoar.lisputils/ |
|
13 |
+git clone --depth=1 https://github.com/fiddlerwoaroof/data-lens.git "$HOME"/quicklisp/local-projects/data-lens/ |
|
14 |
+git clone --depth=1 https://github.com/fiddlerwoaroof/aws-sdk-lisp.git "$HOME"/quicklisp/local-projects/aws-sdk-lisp |
|
15 |
+ |
|
16 |
+pushd "$HOME"/quicklisp/local-projects/aws-sdk-lisp |
|
17 |
+git checkout my-patches |
|
18 |
+popd |
|
11 | 19 |
|
12 |
-ln -s /root/project/ ~/quicklisp/local-projects/daydreamer |
|
20 |
+ln -s /root/project/ "$HOME"/quicklisp/local-projects/daydreamer |
... | ... |
@@ -5,42 +5,42 @@ |
5 | 5 |
(sb-posix:setenv "CC" "clang" 1) |
6 | 6 |
|
7 | 7 |
(defsystem :daydreamer |
8 |
- :description "" |
|
9 |
- :author "Ed L <gh@elangley.org>" |
|
10 |
- :license "MIT" |
|
11 |
- :defsystem-depends-on (#:cffi-grovel) |
|
12 |
- :depends-on (#:alexandria |
|
13 |
- #:uiop |
|
14 |
- #:serapeum |
|
15 |
- #:fwoar-lisputils |
|
16 |
- (:feature (:not :lispworks) |
|
17 |
- #:net.didierverna.clon) |
|
18 |
- #:cl-base64 |
|
19 |
- #:local-time |
|
20 |
- #:osicat |
|
21 |
- #:local-time-duration |
|
22 |
- #:closer-mop |
|
23 |
- #:aws-sdk |
|
24 |
- #:aws-sdk/services/cloudformation |
|
25 |
- #:aws-sdk/services/monitoring |
|
26 |
- #:aws-sdk/services/elasticmapreduce |
|
27 |
- #:should-test |
|
28 |
- #:yason |
|
29 |
- #:hunchentoot |
|
30 |
- #:data-lens |
|
31 |
- #:cffi) |
|
32 |
- :serial t |
|
33 |
- :components ((:file "aws-result") |
|
34 |
- (:file "main") |
|
35 |
- (:file "cli" :if-feature (:not :lispworks))) |
|
8 |
+ :description "" |
|
9 |
+ :author "Ed L <gh@elangley.org>" |
|
10 |
+ :license "MIT" |
|
11 |
+ :defsystem-depends-on (#:cffi-grovel) |
|
12 |
+ :depends-on (#:alexandria |
|
13 |
+ #:uiop |
|
14 |
+ #:serapeum |
|
15 |
+ #:fwoar-lisputils |
|
16 |
+ #:cl-base64 |
|
17 |
+ #:local-time |
|
18 |
+ #:local-time-duration |
|
19 |
+ #:closer-mop |
|
20 |
+ #:aws-sdk |
|
21 |
+ #:aws-sdk/services/cloudformation |
|
22 |
+ #:aws-sdk/services/monitoring |
|
23 |
+ #:aws-sdk/services/elasticmapreduce |
|
24 |
+ #:yason |
|
25 |
+ #:hunchentoot |
|
26 |
+ #:data-lens |
|
27 |
+ #:cffi |
|
28 |
+ (:feature (:not :lispworks) |
|
29 |
+ #:net.didierverna.clon) |
|
30 |
+ (:feature (:not :lispworks) |
|
31 |
+ #:should-test)) |
|
32 |
+ :serial t |
|
33 |
+ :components ((:file "aws-result") |
|
34 |
+ (:file "main") |
|
35 |
+ (:file "cli" :if-feature (:not :lispworks))) |
|
36 | 36 |
|
37 |
- :entry-point "daydreamer.cli::main" |
|
38 |
- #-lispworks |
|
39 |
- :output-files |
|
40 |
- #-lispworks |
|
41 |
- (cffi-toolchain:static-program-op (o c) |
|
42 |
- (format t "~&*dpd* ~s~%%" (merge-pathnames "daydreamer" |
|
43 |
- *default-pathname-defaults*)) |
|
44 |
- (list |
|
45 |
- (merge-pathnames "daydreamer" |
|
46 |
- *default-pathname-defaults*)))) |
|
37 |
+ :entry-point "daydreamer.cli::main" |
|
38 |
+ #-lispworks |
|
39 |
+ :output-files |
|
40 |
+ #-lispworks |
|
41 |
+ (cffi-toolchain:static-program-op (o c) |
|
42 |
+ (format t "~&*dpd* ~s~%%" (merge-pathnames "daydreamer" |
|
43 |
+ *default-pathname-defaults*)) |
|
44 |
+ (list |
|
45 |
+ (merge-pathnames "daydreamer" |
|
46 |
+ *default-pathname-defaults*)))) |
... | ... |
@@ -1,7 +1,7 @@ |
1 | 1 |
;; MIT license Edward Langley (c) 2018 |
2 | 2 |
|
3 | 3 |
(defpackage :daydreamer.main |
4 |
- (:use :cl :fw.lu :alexandria :st :daydreamer.aws-result) |
|
4 |
+ (:use :cl :fw.lu :alexandria :daydreamer.aws-result) |
|
5 | 5 |
(:export main dump |
6 | 6 |
#:stack-parameters |
7 | 7 |
#:stack-outputs |
... | ... |
@@ -35,7 +35,7 @@ |
35 | 35 |
|
36 | 36 |
(defun stack-parameters (the-stack) |
37 | 37 |
(print-kvs "Parameter" |
38 |
- (tagged-kv-formatter "PARAMETERS") t |
|
38 |
+ (tagged-kv-formatter "PARAMETER") t |
|
39 | 39 |
(parameters the-stack))) |
40 | 40 |
|
41 | 41 |
(defun lt-format (a b &key &allow-other-keys) |
... | ... |
@@ -48,10 +48,11 @@ |
48 | 48 |
|
49 | 49 |
(defun every-five-seconds (cb args &optional (delay-function #'sleep)) |
50 | 50 |
(loop |
51 |
- for (continue? . next-args) = (multiple-value-list (apply cb args)) then (multiple-value-list (apply cb next-args)) |
|
52 |
- while continue? |
|
53 |
- do (funcall delay-function 5))) |
|
51 |
+ for (continue? . next-args) = (multiple-value-list (apply cb args)) then (multiple-value-list (apply cb next-args)) |
|
52 |
+ while continue? |
|
53 |
+ do (funcall delay-function 5))) |
|
54 | 54 |
|
55 |
+#+(or) |
|
55 | 56 |
(deftest every-five-seconds () |
56 | 57 |
(let ((counter 0) |
57 | 58 |
delay) |
... | ... |
@@ -85,6 +86,23 @@ |
85 | 86 |
counters) |
86 | 87 |
(should be = 5 delay)))) |
87 | 88 |
|
89 |
+(defun resource-block (the-stack) |
|
90 |
+ (format t "~& RESOURCES ~%============~%") |
|
91 |
+ (let ((resources (daydreamer.aws-result:extract-list |
|
92 |
+ (serapeum:assocdr "StackResources" |
|
93 |
+ (aws/cloudformation:describe-stack-resources |
|
94 |
+ :stack-name (stack-name the-stack)) |
|
95 |
+ :test 'equal) |
|
96 |
+ 'daydreamer.aws-result:extract-stack-resource))) |
|
97 |
+ (loop for resource in resources |
|
98 |
+ do (format t "RESOURCE ~a (~a) ~a ~a~:[~;~%~:*~4t~a~]~%" |
|
99 |
+ (logical-resource-id resource) |
|
100 |
+ (resource-type resource) |
|
101 |
+ (resource-status resource) |
|
102 |
+ (physical-resource-id resource) |
|
103 |
+ (resource-status-reason resource)))) |
|
104 |
+ (format t "~&============~2%")) |
|
105 |
+ |
|
88 | 106 |
(defun parameter-block (the-stack) |
89 | 107 |
(format t "~& PARAMETERS ~%============~%") |
90 | 108 |
(stack-parameters the-stack) |
... | ... |
@@ -100,6 +118,10 @@ |
100 | 118 |
((%stack :initarg :stack :accessor stack) |
101 | 119 |
(%old-status :initarg :old-status :accessor old-status :initform nil))) |
102 | 120 |
|
121 |
+(defmethod stack-name ((stack-formatter stack-formatter)) |
|
122 |
+ (when (slot-boundp stack-formatter '%stack) |
|
123 |
+ (stack-status (stack stack-formatter)))) |
|
124 |
+ |
|
103 | 125 |
(defmethod stack-status ((stack-formatter stack-formatter)) |
104 | 126 |
(when (slot-boundp stack-formatter '%stack) |
105 | 127 |
(stack-status (stack stack-formatter)))) |
... | ... |
@@ -117,7 +139,7 @@ |
117 | 139 |
|
118 | 140 |
(defgeneric refresh (stack-formatter) |
119 | 141 |
(:method ((stack daydreamer.aws-result:stack)) |
120 |
- (stack-for-name (stack-name stack))) |
|
142 |
+ (stack-for-name (stack-name stack))) |
|
121 | 143 |
(:method ((stack-formatter string)) |
122 | 144 |
(make-instance 'stack-formatter :stack (stack-for-name stack-formatter))) |
123 | 145 |
(:method ((stack-formatter stack-formatter)) |
... | ... |
@@ -127,28 +149,34 @@ |
127 | 149 |
(defmethod old-status ((stack daydreamer.aws-result:stack)) |
128 | 150 |
nil) |
129 | 151 |
|
130 |
-(defun stack-info (the-stack) |
|
152 |
+(defun stack-info (the-stack status parameters outputs &optional (resources nil)) |
|
131 | 153 |
(with-accessors ((old-status old-status)) the-stack |
132 | 154 |
(let* ((current-status (stack-status the-stack))) |
133 | 155 |
(unless old-status |
134 |
- (parameter-block the-stack)) |
|
156 |
+ (when parameters |
|
157 |
+ (parameter-block the-stack))) |
|
135 | 158 |
|
136 | 159 |
(unless (equal old-status current-status) |
137 |
- (format t "~&STATUS ~a~%" current-status)) |
|
160 |
+ (when status |
|
161 |
+ (format t "~&STATUS ~a~%" current-status))) |
|
162 |
+ |
|
163 |
+ (when resources |
|
164 |
+ (terpri) |
|
165 |
+ (resource-block the-stack)) |
|
138 | 166 |
|
139 | 167 |
(if (ends-with-subseq "COMPLETE" (symbol-name current-status)) |
140 |
- (output-block the-stack) |
|
168 |
+ (when outputs |
|
169 |
+ (output-block the-stack)) |
|
141 | 170 |
t)))) |
142 | 171 |
|
143 |
-(defmacro refreshing (cb) |
|
172 |
+(defmacro refreshing (cb &rest args) |
|
144 | 173 |
`(lambda (thing) |
145 | 174 |
(let ((refreshed-thing (refresh thing))) |
146 |
- (values (,cb refreshed-thing) |
|
175 |
+ (values (,cb refreshed-thing ,@args) |
|
147 | 176 |
refreshed-thing)))) |
148 | 177 |
|
149 | 178 |
(defun watch-stack (name) |
150 | 179 |
(format t "~&Watching ~s~2%" name) |
151 |
- (every-five-seconds (refreshing stack-info) |
|
180 |
+ (every-five-seconds (refreshing stack-info t t t) |
|
152 | 181 |
(list name)) |
153 | 182 |
(fresh-line)) |
154 |
- |
... | ... |
@@ -3,6 +3,6 @@ export ASDF_OUTPUT_TRANSLATIONS="/:" CC="clang" |
3 | 3 |
|
4 | 4 |
env |
5 | 5 |
|
6 |
-sbcl --no-userinit --disable-debugger --load /root/quicklisp/setup.lisp --load build.lisp |
|
6 |
+sbcl --no-userinit --disable-debugger --load "$HOME"/quicklisp/setup.lisp --load build.lisp |
|
7 | 7 |
|
8 | 8 |
./daydreamer --self-test |