Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WiP] Reconfigurable grid weave secret #2583

Open
wants to merge 5 commits into
base: refactor/agent-weave
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions agent/lib/kontena/launchers/weave.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ class Weave

CONTAINER_NAME = 'weave'

def weave_password
ENV['KONTENA_TOKEN']
end

# @param node_info [Kontena::Actor::Observable<Kontena::Models::NodeInfo>]
def initialize(start: true)
async.start if start
Expand Down Expand Up @@ -57,7 +53,7 @@ def ensure(node)

state = {}
state.merge! self.ensure_container(IMAGE,
password: self.weave_password,
password: node.weave_secret,
trusted_subnets: node.grid_trusted_subnets
)
state.merge! self.ensure_peers(node.peer_ips)
Expand Down
6 changes: 6 additions & 0 deletions agent/lib/kontena/models/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def initialize(data)
@node_number = data['node_number']
@initial_member = data['initial_member']
@grid = data['grid']
@weave = data['grid']['weave']
end

def statsd_conf
Expand All @@ -49,6 +50,11 @@ def grid_supernet
@grid['supernet']
end

# @return [String]
def weave_secret
@weave['secret']
end

# @return [IPAddress] 10.81.0.X
def overlay_ip
IPAddress.parse(@overlay_ip)
Expand Down
1 change: 1 addition & 0 deletions cli/lib/kontena/cli/grid_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class Kontena::Cli::GridCommand < Kontena::Command
subcommand ["list","ls"], "List all grids", load_subcommand('grids/list_command')
subcommand "create", "Create a new grid", load_subcommand('grids/create_command')
subcommand "update", "Update grid", load_subcommand('grids/update_command')
subcommand "reset-token", "Reset grid tokens", load_subcommand('grids/reset_token_command')
subcommand "use", "Switch to use specific grid", load_subcommand('grids/use_command')
subcommand "show", "Show grid details", load_subcommand('grids/show_command')
subcommand "logs", "Show logs from grid containers", load_subcommand('grids/logs_command')
Expand Down
24 changes: 24 additions & 0 deletions cli/lib/kontena/cli/grids/reset_token_command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Kontena::Cli::Grids
class ResetTokenCommand < Kontena::Command
include Kontena::Cli::Common
include Kontena::Cli::GridOptions

requires_current_master
requires_current_master_token
requires_current_grid

parameter "[GRID]", "Grid name"

option "--force", :flag, "Force token update"

def execute
confirm("Resetting the grid weave secrets will temporarily disrupt the overlay network, and cause transient service errors. Are you sure?")

data = {}

spinner "Resetting grid #{current_grid.colorize(:cyan)} token" do
client.post("grids/#{current_grid}/token", data)
end
end
end
end
1 change: 1 addition & 0 deletions server/app/models/grid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Grid
field :default_affinity, type: Array, default: []
field :subnet, type: String, default: SUBNET
field :supernet, type: String, default: SUPERNET
field :weave_secret, type: String

has_many :host_nodes, dependent: :destroy
has_many :host_node_stats
Expand Down
15 changes: 15 additions & 0 deletions server/app/mutations/grids/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ def self.included(base)
base.extend(ClassMethods)
end

def reschedule_grid(grid)
GridScheduler.new(grid).reschedule
end

def notify_nodes(grid)
grid.host_nodes.connected.each do |node|
plugger = Agent::NodePlugger.new(node)
plugger.send_node_info
end
rescue => exc
Logging.logger.error(self.class.name) { exc }
else
Logging.logger.info(self.class.name) { "notified grid #{grid.to_path} nodes" }
end

module ClassMethods
def common_validations
# common inputs for both create + update
Expand Down
15 changes: 4 additions & 11 deletions server/app/mutations/grids/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,12 @@ def execute
return
end

self.notify_nodes
Celluloid::Future.new do
self.notify_nodes(self.grid)
self.reschedule_grid(self.grid)
end

self.grid
end

def notify_nodes
Celluloid::Future.new {
grid.host_nodes.connected.each do |node|
plugger = Agent::NodePlugger.new(grid, node)
plugger.send_node_info
end
GridScheduler.new(grid).reschedule
}
end
end
end
41 changes: 41 additions & 0 deletions server/app/mutations/grids/update_token.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require_relative 'common'

module Grids
class UpdateToken < Mutations::Command
include Common

required do
model :grid
model :user
end

def validate
add_error(:user, :invalid, 'Operation not allowed') unless user.can_update?(grid)
end

def generate_secret
SecureRandom.base64(64)
end

def update_weave_secret(grid)
grid.weave_secret = self.generate_secret
end

def execute
update_weave_secret(self.grid)

unless self.grid.save
self.grid.errors.each do |key, message|
add_error(key, :invalid, message)
end
return
end

Celluloid::Future.new do
notify_nodes(self.grid)
end

self.grid
end
end
end
19 changes: 19 additions & 0 deletions server/app/routes/v1/grids_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,25 @@ class GridsApi < Roda
r.route 'grid_event_logs'
end

r.on 'token' do
r.post do
r.is do
data = parse_json_body
data[:grid] = @grid
data[:user] = current_user
outcome = Grids::UpdateToken.run(data)
if outcome.success?
@grid = outcome.result
audit_event(r, @grid, @grid, 'update-token')
response.status = 201
else
response.status = 422
{error: outcome.errors.message}
end
end
end
end

r.get do
r.is do
render('grids/show')
Expand Down
7 changes: 7 additions & 0 deletions server/app/serializers/rpc/grid_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class GridSerializer < RpcSerializer
attribute :supernet
attribute :stats
attribute :logs
attribute :weave

def id
object.to_path
Expand All @@ -29,5 +30,11 @@ def logs
}
end
end

def weave
{
secret: object.weave_secret,
}
end
end
end
7 changes: 7 additions & 0 deletions server/db/migrations/27_grid_weave_secret.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class GridWeaveSecret < Mongodb::Migration
def self.up
Grid.all.each do |grid|
grid.set(:weave_secret => grid.token)
end
end
end