Deploy platform-specific nebula.

This commit is contained in:
Kaitlyn Parkhurst 2021-06-18 20:51:40 -07:00
parent fab24b15ee
commit 44d5954b7d
5 changed files with 71 additions and 6 deletions

View file

@ -2,7 +2,7 @@
- name: Install nebula binary
copy:
dest: /usr/local/sbin/nebula
src: "{{ role_path }}/files/nebula"
src: "{{ nebula_binary }}"
owner: root
group: root
mode: 0755

View file

@ -11,7 +11,12 @@ sub deploy ($c) {
my $node = $c->db->resultset('Node')->find( $c->param('node_id') );
my @keys = $c->db->resultset('Sshkey')->all();
$c->stash( node => $node, sshkeys => \@keys );
$c->stash(
node => $node,
sshkeys => \@keys,
platforms => $c->nebula_platforms,
);
}
sub create ($c) {
@ -19,7 +24,12 @@ sub create ($c) {
my $node = $c->db->resultset('Node')->find( $c->param('node_id') );
my $job_id = $c->minion->enqueue(
deploy_node => [ $node->id, $c->param('sshkey_id'), $c->param('deploy_ip') ],
deploy_node => [
$node->id,
$c->param('sshkey_id'),
$c->param('deploy_ip'),
$c->param('platform'),
],
{ notes => { $node->hostname => 1 } }
);

View file

@ -1,5 +1,6 @@
package MeshMage::Web::Plugin::Helpers;
use Mojo::Base 'Mojolicious::Plugin', -signatures;
use File::Find;
sub register ( $self, $app, $config ) {
@ -17,6 +18,50 @@ sub register ( $self, $app, $config ) {
);
});
# Helpers to get the nebula/nebula_cert binary paths for the
# system running MeshMage.
$app->helper( nebula_cert => sub ($c) {
return state $nebula_cert = sprintf( "%s/%s/nebula_cert",
$c->config->{nebula}{store}, $c->config->{nebula}{use}
);
});
$app->helper( nebula => sub ($c) {
return state $nebula_cert = sprintf( "%s/%s/nebula",
$c->config->{nebula}{store}, $c->config->{nebula}{use}
);
});
# Helper to get the nebula binary path for systems we're uploading
# to.
$app->helper( nebula_for => sub ($c, $platform) {
return sprintf("%s/%s/nebula", $c->config->{nebula}{store}, $platform);
});
# Helper to memoize the platforms list.
$app->helper( nebula_platforms => sub ($c) {
return state $platforms = _get_platforms($c->config->{nebula}{store});
});
}
# List all of the platform combinations, like linux/amd64
# that are in the .nebula directory.
sub _get_platforms ($path) {
my %platforms;
find({
wanted => sub {
return if $path eq $_; # no top dir
my $rel = substr($_, (length($path) + 1) ); # $rel is linux/amd64/...
my ( $os, $arch ) = split( m|/|, $rel ); # just first 2 segments
return unless $os && $arch; # ensure both exist
$platforms{"$os/$arch"} = 1; # hash to unique
},
no_chdir => 1,
}, $path );
return [ sort { $a cmp $b } keys %platforms ];
}
1;

View file

@ -30,7 +30,7 @@ sub register ( $self, $app, $config ) {
unless $count == 1;
# Create the network cert and signing key.
run3( [ $job->app->config->{nebula}->{nebula_cert}, 'ca',
run3( [ $job->app->nebula_cert, 'ca',
'-out-crt', $job->app->filepath_for(nebula => $network->id, 'ca.crt'),
'-out-key', $job->app->filepath_for(nebula => $network->id, 'ca.key'),
'-name' , $network_name,
@ -104,7 +104,7 @@ sub register ( $self, $app, $config ) {
};
});
$app->minion->add_task( deploy_node => sub ( $job, $node_id, $key_id, $deploy_ip ) {
$app->minion->add_task( deploy_node => sub ( $job, $node_id, $key_id, $deploy_ip, $platform ) {
my $node = $job->app->db->resultset('Node')->find( $node_id );
my @lighthouses = $node->network->search_related( 'nodes', { is_lighthouse => 1 } );
@ -127,6 +127,7 @@ sub register ( $self, $app, $config ) {
print $playbook " ansible_ssh_common_args: -oControlMaster=auto -oControlPersist=60s -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no\n";
print $playbook " domain: " . $node->hostname . "\n";
print $playbook " meshnet_store: " . $job->app->filepath_for( 'nebula' ) . "\n";
print $playbook " nebula_binary: " . $job->app->nebula_for( $platform ) . "\n";
print $playbook " network_id: " . $node->network->id . "\n";
print $playbook " node:\n";
print $playbook " is_lighthouse: " . $node->is_lighthouse . "\n";
@ -194,7 +195,7 @@ sub register ( $self, $app, $config ) {
( $public ? ( public_ip => $public ) : () ),
});
my $command = [ $job->app->config->{nebula}->{nebula_cert}, 'sign',
my $command = [ $job->app->nebula_cert, 'sign',
'-ca-crt', $job->app->filepath_for( nebula => $network->id, "ca.crt" ),
'-ca-key', $job->app->filepath_for( nebula => $network->id, "ca.key" ),
'-name', $domain,

View file

@ -37,6 +37,15 @@
</select>
</div>
<div class="mb-3">
<label for="platform">Target Platform</label>
<select class="form-control" name="platform" id="platform">
%% for $platforms -> $platform {
<option value="[% $platform %]">[% $platform %]</option>
%% }
</select>
</div>
%% include '_base/form/input.tx' { type => 'text', name => 'deploy_ip',
%% title => 'SSH IP',
%% help => 'This is the IP that MeshMage will connect to to install Nebula',