]>
git.proxmox.com Git - pmg-api.git/blob - PMG/API2/Cluster.pm
1 package PMG
::API2
::Cluster
;
8 use PVE
::Tools
qw(extract_param);
9 use HTTP
::Status
qw(:constants);
10 use Storable
qw(dclone);
11 use PVE
::JSONSchema
qw(get_standard_option);
14 use PVE
::APIClient
::LWP
;
16 use PMG
::RESTEnvironment
;
17 use PMG
::ClusterConfig
;
21 use base
qw(PVE::RESTHandler);
24 my ($cfg, $conn_setup) = @_;
26 my $conn = PVE
::APIClient
::LWP-
>new(%$conn_setup);
28 my $info = PMG
::Cluster
::read_local_cluster_info
();
30 my $res = $conn->post("/config/cluster/nodes", $info);
32 foreach my $node (@$res) {
33 $cfg->{ids
}->{$node->{cid
}} = $node;
39 __PACKAGE__-
>register_method({
43 description
=> "Directory index.",
44 permissions
=> { user
=> 'all' },
46 additionalProperties
=> 0,
55 links
=> [ { rel
=> 'child', href
=> "{name}" } ],
69 __PACKAGE__-
>register_method({
73 description
=> "Cluster node index.",
74 # alway read local file
76 additionalProperties
=> 0,
79 permissions
=> { check
=> [ 'admin' ] },
85 cid
=> { type
=> 'integer' },
88 links
=> [ { rel
=> 'child', href
=> "{cid}" } ],
93 my $cfg = PVE
::INotify
::read_file
('cluster.conf');
95 if (scalar(keys %{$cfg->{ids
}})) {
96 my $role = $cfg->{local}->{type
} // '-';
98 die "local node '$cfg->{local}->{name}' not part of cluster\n";
102 return PVE
::RESTHandler
::hash_to_array
($cfg->{ids
}, 'cid');
105 my $add_node_schema = PMG
::ClusterConfig
::Node-
>createSchema(1);
106 delete $add_node_schema->{properties
}->{cid
};
108 __PACKAGE__-
>register_method({
112 description
=> "Add an node to the cluster config.",
115 parameters
=> $add_node_schema,
117 description
=> "Returns the resulting node list.",
122 cid
=> { type
=> 'integer' },
130 my $cfg = PMG
::ClusterConfig-
>new();
132 die "no cluster defined\n" if !scalar(keys %{$cfg->{ids
}});
134 my $master = $cfg->{master
} || die "unable to lookup master node\n";
137 foreach my $cid (keys %{$cfg->{ids
}}) {
138 my $d = $cfg->{ids
}->{$cid};
140 if ($d->{type
} eq 'node' && $d->{ip
} eq $param->{ip
} && $d->{name
} eq $param->{name
}) {
141 $next_cid = $cid; # allow overwrite existing node data
145 if ($d->{ip
} eq $param->{ip
}) {
146 die "ip address '$param->{ip}' is already used by existing node $d->{name}\n";
149 if ($d->{name
} eq $param->{name
}) {
150 die "node with name '$param->{name}' already exists\n";
154 if (!defined($next_cid)) {
155 $next_cid = ++$master->{maxcid
};
160 cid
=> $master->{maxcid
},
163 foreach my $k (qw(ip name hostrsapubkey rootrsapubkey fingerprint)) {
164 $node->{$k} = $param->{$k};
167 $cfg->{ids
}->{$node->{cid
}} = $node;
171 return PVE
::RESTHandler
::hash_to_array
($cfg->{ids
}, 'cid');
174 return PMG
::ClusterConfig
::lock_config
($code, "add node failed");
177 __PACKAGE__-
>register_method({
181 description
=> "Create initial cluster config with current node as master.",
182 # alway read local file
184 additionalProperties
=> 0,
188 returns
=> { type
=> 'string' },
192 my $rpcenv = PMG
::RESTEnvironment-
>get();
193 my $authuser = $rpcenv->get_user();
196 my $cfg = PMG
::ClusterConfig-
>new();
198 die "cluster alreayd defined\n" if scalar(keys %{$cfg->{ids
}});
200 my $info = PMG
::Cluster
::read_local_cluster_info
();
204 $info->{type
} = 'master';
206 $info->{maxcid
} = $cid,
208 $cfg->{ids
}->{$cid} = $info;
211 #my $service_list = [ 'pmgpolicy', 'pmgmirror', 'pmgtunnel', 'pmg-smtp-filter' ];
212 my $service_list = [ 'pmgpolicy', 'pmg-smtp-filter' ];
214 print STDERR
"stop all services accessing the database\n";
215 # stop all services accessing the database
216 PMG
::Utils
::service_wait_stopped
(40, $service_list);
218 print STDERR
"save new cluster configuration\n";
221 PMG
::DBTools
::init_masterdb
($cid);
223 PMG
::Cluster
::create_needed_dirs
($cid, 1);
225 print STDERR
"cluster master successfully created\n";
229 foreach my $service (reverse @$service_list) {
230 eval { PVE
::Tools
::run_command
(['systemctl', 'start', $service]); };
238 return $rpcenv->fork_worker('clustercreate', undef, $authuser, $realcmd);
241 return PMG
::ClusterConfig
::lock_config
($code, "create cluster failed");
244 __PACKAGE__-
>register_method({
248 description
=> "Join local node to an existing cluster.",
249 # alway read local file
251 additionalProperties
=> 0,
254 description
=> "IP address.",
255 type
=> 'string', format
=> 'ip',
258 description
=> "SSL certificate fingerprint.",
260 pattern
=> '^(:?[A-Z0-9][A-Z0-9]:){31}[A-Z0-9][A-Z0-9]$',
263 description
=> "Superuser password.",
269 returns
=> { type
=> 'null' },
274 my $cfg = PMG
::ClusterConfig-
>new();
276 die "cluster alreayd defined\n" if scalar(keys %{$cfg->{ids
}});
279 username
=> 'root@pam',
280 password
=> $param->{password
},
281 cookie_name
=> 'PMGAuthCookie',
282 host
=> $param->{master_ip
},
283 cached_fingerprints
=> {
284 $param->{fingerprint
} => 1,
288 cluster_join
($cfg, $setup);
291 PMG
::ClusterConfig
::lock_config
($code, "cluster join failed");