From 44d5954b7da6bd6ca6b1ff4cc72f85e08b0a563d Mon Sep 17 00:00:00 2001 From: Kaitlyn Parkhurst Date: Fri, 18 Jun 2021 20:51:40 -0700 Subject: [PATCH] Deploy platform-specific nebula. --- Ansible/roles/meshmage-node/tasks/main.yml | 2 +- Web/lib/MeshMage/Web/Controller/Deploy.pm | 14 ++++++- Web/lib/MeshMage/Web/Plugin/Helpers.pm | 45 ++++++++++++++++++++++ Web/lib/MeshMage/Web/Plugin/MinionTasks.pm | 7 ++-- Web/templates/deploy/deploy.html.tx | 9 +++++ 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/Ansible/roles/meshmage-node/tasks/main.yml b/Ansible/roles/meshmage-node/tasks/main.yml index 655a15d..70bb28b 100644 --- a/Ansible/roles/meshmage-node/tasks/main.yml +++ b/Ansible/roles/meshmage-node/tasks/main.yml @@ -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 diff --git a/Web/lib/MeshMage/Web/Controller/Deploy.pm b/Web/lib/MeshMage/Web/Controller/Deploy.pm index 3c65051..cd2f028 100644 --- a/Web/lib/MeshMage/Web/Controller/Deploy.pm +++ b/Web/lib/MeshMage/Web/Controller/Deploy.pm @@ -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 } } ); diff --git a/Web/lib/MeshMage/Web/Plugin/Helpers.pm b/Web/lib/MeshMage/Web/Plugin/Helpers.pm index 425608b..421b3b6 100644 --- a/Web/lib/MeshMage/Web/Plugin/Helpers.pm +++ b/Web/lib/MeshMage/Web/Plugin/Helpers.pm @@ -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; diff --git a/Web/lib/MeshMage/Web/Plugin/MinionTasks.pm b/Web/lib/MeshMage/Web/Plugin/MinionTasks.pm index 403cf44..4ba7f85 100644 --- a/Web/lib/MeshMage/Web/Plugin/MinionTasks.pm +++ b/Web/lib/MeshMage/Web/Plugin/MinionTasks.pm @@ -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, diff --git a/Web/templates/deploy/deploy.html.tx b/Web/templates/deploy/deploy.html.tx index 724f571..b84c34b 100644 --- a/Web/templates/deploy/deploy.html.tx +++ b/Web/templates/deploy/deploy.html.tx @@ -37,6 +37,15 @@ +
+ + +
+ %% 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',