]>
Commit | Line | Data |
---|---|---|
cba17aeb DM |
1 | package PMG::CLI::pmgcm; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use Data::Dumper; | |
e16a9efc DM |
6 | use Term::ReadLine; |
7 | use JSON; | |
cba17aeb DM |
8 | |
9 | use PVE::SafeSyslog; | |
10 | use PVE::Tools qw(extract_param); | |
11 | use PVE::INotify; | |
12 | use PVE::CLIHandler; | |
13 | ||
cfdf6608 | 14 | use PMG::RESTEnvironment; |
cba17aeb DM |
15 | use PMG::DBTools; |
16 | use PMG::Cluster; | |
17 | use PMG::ClusterConfig; | |
fb5f2d1e | 18 | use PMG::API2::Cluster; |
cba17aeb DM |
19 | |
20 | use base qw(PVE::CLIHandler); | |
21 | ||
cfdf6608 DM |
22 | sub setup_environment { |
23 | PMG::RESTEnvironment->setup_default_cli_env(); | |
24 | } | |
25 | ||
26 | my $upid_exit = sub { | |
27 | my $upid = shift; | |
28 | my $status = PVE::Tools::upid_read_status($upid); | |
29 | exit($status eq 'OK' ? 0 : -1); | |
30 | }; | |
31 | ||
cba17aeb DM |
32 | my $format_nodelist = sub { |
33 | my $res = shift; | |
34 | ||
3862c23d DM |
35 | if (!scalar(@$res)) { |
36 | print "no cluster defined\n"; | |
37 | return; | |
38 | } | |
39 | ||
cba17aeb DM |
40 | print "NAME(CID)--------------IPADDRESS----ROLE-STATE---------UPTIME---LOAD----MEM---DISK\n"; |
41 | foreach my $ni (@$res) { | |
42 | my $state = '?'; | |
3879a8aa DM |
43 | |
44 | printf "%-20s %-15s %-6s %1s %15s %6s %5s%% %5s%%\n", | |
45 | "$ni->{name}($ni->{cid})", $ni->{ip}, $ni->{type}, | |
cba17aeb DM |
46 | $state, '-', '-', '-', '-'; |
47 | } | |
48 | }; | |
49 | ||
3879a8aa DM |
50 | __PACKAGE__->register_method({ |
51 | name => 'join_cmd', | |
52 | path => 'join_cmd', | |
53 | method => 'GET', | |
cf9a8dea | 54 | description => "Prints the command for joining an new node to the cluster. You need to execute the command on the new node.", |
3879a8aa DM |
55 | parameters => { |
56 | additionalProperties => 0, | |
57 | properties => {}, | |
58 | }, | |
59 | returns => { type => 'null' }, | |
60 | code => sub { | |
61 | my ($param) = @_; | |
62 | ||
63 | my $cfg = PVE::INotify::read_file('cluster.conf'); | |
64 | ||
65 | if (scalar(keys %{$cfg->{ids}})) { | |
66 | ||
67 | my $master = $cfg->{master} || | |
68 | die "no master found\n"; | |
69 | ||
e16a9efc | 70 | print "pmgcm join $master->{ip} --fingerprint $master->{fingerprint}\n"; |
3879a8aa DM |
71 | |
72 | } else { | |
73 | die "no cluster defined\n"; | |
74 | } | |
75 | ||
76 | return undef; | |
77 | }}); | |
78 | ||
e16a9efc DM |
79 | __PACKAGE__->register_method({ |
80 | name => 'join', | |
81 | path => 'join', | |
82 | method => 'GET', | |
83 | description => "Join a new node to an existing cluster.", | |
84 | parameters => { | |
85 | additionalProperties => 0, | |
86 | properties => { | |
87 | master_ip => { | |
88 | description => "IP address.", | |
89 | type => 'string', format => 'ip', | |
90 | }, | |
91 | fingerprint => { | |
92 | description => "SSL certificate fingerprint.", | |
93 | type => 'string', | |
94 | pattern => '^(:?[A-Z0-9][A-Z0-9]:){31}[A-Z0-9][A-Z0-9]$', | |
95 | optional => 1, | |
96 | }, | |
97 | }, | |
98 | }, | |
99 | returns => { type => 'null' }, | |
100 | code => sub { | |
101 | my ($param) = @_; | |
102 | ||
103 | my $code = sub { | |
275d6d6d | 104 | my $cfg = PMG::ClusterConfig->new(); |
e16a9efc DM |
105 | |
106 | die "cluster alreayd defined\n" if scalar(keys %{$cfg->{ids}}); | |
107 | ||
108 | my $term = new Term::ReadLine ('pmgcm'); | |
109 | my $attribs = $term->Attribs; | |
110 | $attribs->{redisplay_function} = $attribs->{shadow_redisplay}; | |
111 | my $password = $term->readline('Enter password: '); | |
112 | ||
113 | my $setup = { | |
114 | username => 'root@pam', | |
115 | password => $password, | |
116 | cookie_name => 'PMGAuthCookie', | |
117 | host => $param->{master_ip}, | |
118 | }; | |
119 | if ($param->{fingerprint}) { | |
120 | $setup->{cached_fingerprints} = { | |
121 | $param->{fingerprint} => 1, | |
122 | }; | |
123 | } else { | |
124 | # allow manual fingerprint verification | |
125 | $setup->{manual_verification} = 1; | |
126 | } | |
127 | ||
275d6d6d | 128 | PMG::API2::Cluster::cluster_join($cfg, $setup); |
e16a9efc DM |
129 | }; |
130 | ||
131 | PMG::ClusterConfig::lock_config($code, "cluster join failed"); | |
132 | ||
133 | return undef; | |
134 | }}); | |
135 | ||
cba17aeb | 136 | our $cmddef = { |
fb5f2d1e | 137 | nodes => [ 'PMG::API2::Cluster', 'nodes', [], {}, $format_nodelist], |
cfdf6608 | 138 | create => [ 'PMG::API2::Cluster', 'create', [], {}, $upid_exit], |
e16a9efc | 139 | join => [ __PACKAGE__, 'join', ['master_ip']], |
3879a8aa | 140 | join_cmd => [ __PACKAGE__, 'join_cmd', []], |
cba17aeb DM |
141 | }; |
142 | ||
143 | 1; |