KeyMangler example app
[scpubgit/DKit.git] / lib / App / KeyMangler.pm
CommitLineData
91d1f239 1package App::KeyMangler;
2
3use Moo;
4
5extends 'DX::Tcl';
6
7sub BUILD {
8 my ($self) = @_;
9 our $Tcl_Data ||= do { local $/; my $data = <DATA>; close(DATA); $data };
10 $self->tcl->Eval($Tcl_Data);
11}
12
13sub run {
14 my ($self, @args) = @_;
15 if (@args) {
16 my $res = $self->tcl->call(km => @args);
17 print $res;
18 } else {
19 $self->repl
20 }
21}
22
231;
24
25__DATA__
26
27rule dot_ssh_on { A D } {
28 home_dir_on A H
29 directory_in H '.ssh' D
30 mode D '0700'
31}
32
33rule authorized_keys_on { A F } {
34 dot_ssh_on A D
35 file_in D 'authorized_keys' F
36 mode F '0600'
37}
38
39rule key_installed_on { A K } {
40 authorized_keys_on A F
41 contains_line F K
42}
43
44rule key_not_installed_on { A K } {
45 authorized_keys_on A F
46 not_contains_line F K
47}
48
49rule my_config_dir D {
50 home_dir_on '' H
51 directory_in H '.keymangler' D
52}
53
54rule my_config_file { C F } {
55 my_config_dir D
56 file_in D C F
57}
58
59rule config_contains_line { C L } {
60 my_config_file C F
61 contains_line F L
62}
63
64rule config_not_contains_line { C L } {
65 my_config_file C F
66 not_contains_line F L
67}
68
69rule known_account A { config_contains_line 'accounts' A }
70rule known_key K { config_contains_line 'keys' K }
71rule known_dead D { config_contains_line 'keys.dead' D }
72
73rule not_known_account A { config_not_contains_line 'accounts' A }
74rule not_known_key K { config_not_contains_line 'keys' K }
75rule not_known_dead D { config_not_contains_line 'keys.dead' D }
76
77rule all_known_installed_on A {
78 foreach K { known_key K } { key_installed_on A K }
79}
80
81rule all_dead_not_installed_on A {
82 foreach K { known_dead K } { key_not_installed_on A K }
83}
84
85rule account_synchronized A {
86 all_known_installed_on A
87 all_dead_not_installed_on A
88}
89
90rule all_synchronized {} {
91 foreach A { known_account A } { account_synchronized A }
92}
93
94rule unknown_installed_on { A K } {
95 key_installed_on A K
96 not { known_key K }
97 not { known_dead K }
98}
99
100rule known_installed_on { A K } {
101 key_installed_on A K
102 known_key K
103}
104
105rule dead_installed_on { A K } {
106 key_installed_on A K
107 known_dead K
108}
109
110oo::class create ConfigSet {
111 constructor mytype {
112 namespace import ::DX::*
113 variable type $mytype
114 }
115 method learn V {
116 variable type
117 ensure "known_$type {'$V'}"
118 }
119 method forget V {
120 variable type
121 ensure "not_known_$type {'$V'}"
122 }
123 method list {} {
124 variable type
125 query* "known_$type V" {puts $V}
126 }
127}
128
129oo::class create KeyMangler {
130 constructor {} {
131 namespace import ::DX::*
132 ConfigSet create key key
133 ConfigSet create dead dead
134 ConfigSet create account account
135 variable mode ensure
136 }
137
138 method key args { key {*}$args }
139 method dead args { dead {*}$args }
140 method account args { account {*}$args }
141
142 method status {} {
143 query* {
144 known_account A
145 findall Known K { known_installed_on A K }
146 findall Unknown U { unknown_installed_on A U }
147 findall Dead D { dead_installed_on A D }
148 } {
149 puts "Host: $A"
150 foreach k $Known { puts " Known: [lindex $k 2]" }
151 foreach u $Unknown { puts " Unknown: [lindex $u 2]" }
152 foreach d $Dead { puts " Dead: [lindex $d 2]" }
153 puts ""
154 }
155 }
156
157 method -n args {
158 variable mode solve
159 my {*}$args
160 }
161
162 export -n
163
164 method sync {{account -}} {
165 variable mode
166 if {"$account" eq "-"} {
167 $mode { all_synchronized }
168 } else {
169 $mode "account_synchronized {'$account'}"
170 }
171 }
172}
173
174KeyMangler create km