11 changed files with 241 additions and 54 deletions
-
37add-host-workflow.md
-
4app/controllers/application_controller.rb
-
11app/controllers/dashboard_controller.rb
-
11app/models/certificate.rb
-
45app/models/lxd/api.rb
-
54app/models/lxd/api/v1_0.rb
-
29app/models/lxd/certificate.rb
-
15app/models/lxd/config.rb
-
50app/models/lxd/connection.rb
-
23app/models/lxd/server.rb
-
16app/views/dashboard/index.html.erb
@ -0,0 +1,37 @@ |
|||||
|
# Workflow for adding a LXD host |
||||
|
|
||||
|
## User input |
||||
|
|
||||
|
* A symbolic name |
||||
|
* The LDX host base URL |
||||
|
* The password for certificate addition |
||||
|
|
||||
|
## workflow |
||||
|
|
||||
|
* Check our current client key. |
||||
|
* Recreate client key if we find no active valid key |
||||
|
* This also involves deactivating the old one and activate the new one. |
||||
|
* Get API version of the LXD host. (unauth) |
||||
|
* Bail out if not supported ... currently (only 1.0 is supported) |
||||
|
* Get Server info / well, this might also be done in the previous task. |
||||
|
* If unathorized add cert with password. |
||||
|
* I guess thats it. |
||||
|
|
||||
|
## stored |
||||
|
|
||||
|
* The new cert eventually |
||||
|
* The name and url of the LXD host |
||||
|
|
||||
|
# Workflow accessing LXD host |
||||
|
|
||||
|
## input |
||||
|
|
||||
|
* The name of the LXD host |
||||
|
|
||||
|
## workflow |
||||
|
|
||||
|
* Check our current client cert. |
||||
|
* If close to expiration create a new one and send it to |
||||
|
LXD host with the old one. |
||||
|
* If behind expiration ask for password |
||||
|
* Connect to LXD host using the current active cert. |
||||
@ -0,0 +1,45 @@ |
|||||
|
module Lxd::API |
||||
|
def self.get host, certificate |
||||
|
uri = URI.parse host.uri |
||||
|
con = Net::HTTP.new uri.host, uri.port |
||||
|
con.use_ssl = true |
||||
|
con.cert = OpenSSL::X509::Certificate.new certificate.cert |
||||
|
con.key = OpenSSL::PKey::RSA.new certificate.key |
||||
|
con.verify_mode = OpenSSL::SSL::VERIFY_NONE |
||||
|
|
||||
|
resp = self.call con, Net::HTTP::Get.new('/') |
||||
|
raise "unsupported api version" unless resp['metadata'].include? '/1.0' |
||||
|
Lxd::API::V1_0.new con |
||||
|
end |
||||
|
|
||||
|
def self.call con, req |
||||
|
resp = con.request req |
||||
|
raise "request failure: " + resp.code unless resp.code != 200 |
||||
|
JSON.parse resp.body |
||||
|
end |
||||
|
|
||||
|
def initialize con |
||||
|
@con = con |
||||
|
end |
||||
|
|
||||
|
def call req |
||||
|
handle_response(Lxd::API.call @con, req) |
||||
|
end |
||||
|
|
||||
|
def get uri |
||||
|
call Net::HTTP::Get.new uri |
||||
|
end |
||||
|
|
||||
|
def put uri, data={} |
||||
|
request = Net::HTTP::Put.new uri |
||||
|
request.body = data.to_json |
||||
|
call request |
||||
|
end |
||||
|
|
||||
|
def post uri, data={} |
||||
|
request = Net::HTTP::Post.new uri |
||||
|
request.body = data.to_json |
||||
|
call request |
||||
|
end |
||||
|
end |
||||
|
# vim: set ts=2 sw=2: |
||||
@ -0,0 +1,54 @@ |
|||||
|
class Lxd::API::V1_0 |
||||
|
include Lxd::API |
||||
|
|
||||
|
def config |
||||
|
get '/1.0' |
||||
|
end |
||||
|
|
||||
|
def config= config={} |
||||
|
put '/1.0', config: config |
||||
|
end |
||||
|
|
||||
|
def certificates |
||||
|
get '/1.0/certificates'.map { |uri| |
||||
|
{ |
||||
|
:uri => uri, |
||||
|
:cert => get(uri) |
||||
|
} |
||||
|
} |
||||
|
end |
||||
|
|
||||
|
def add_certificate cert={} |
||||
|
# TODO validate hash |
||||
|
post '/1.0/certificates', cert |
||||
|
end |
||||
|
|
||||
|
def handle_response resp |
||||
|
""" |
||||
|
100 Operation created |
||||
|
101 Started |
||||
|
102 Stopped |
||||
|
103 Running |
||||
|
104 Cancelling |
||||
|
105 Pending |
||||
|
106 Starting |
||||
|
107 Stopping |
||||
|
108 Aborting |
||||
|
109 Freezing |
||||
|
110 Frozen |
||||
|
111 Thawed |
||||
|
200 Success |
||||
|
400 Failure |
||||
|
401 Cancelled |
||||
|
|
||||
|
|
||||
|
100 to 199: resource state (started, stopped, ready, ...) |
||||
|
200 to 399: positive action result |
||||
|
400 to 599: negative action result |
||||
|
600 to 999: future use |
||||
|
""" |
||||
|
raise "api error" if [400..500].include? resp['error_code'] |
||||
|
resp['metadata'] |
||||
|
end |
||||
|
end |
||||
|
# vim: set ts=2 sw=2: |
||||
@ -1,25 +1,22 @@ |
|||||
class Lxd::Certificate |
class Lxd::Certificate |
||||
include ActiveModel::Model |
include ActiveModel::Model |
||||
|
|
||||
def save(host, certificate) |
|
||||
all = Array.new; |
|
||||
|
attr_accessor :api, :type, :certificate, :fingerprint |
||||
|
|
||||
uri = URI.parse(host.uri + '/1.0/certificates') |
|
||||
http = Net::HTTP.new(uri.host, uri.port) |
|
||||
http.use_ssl = true |
|
||||
http.cert = OpenSSL::X509::Certificate.new(certificate.cert) |
|
||||
http.key = OpenSSL::PKey::RSA.new(certificate.key) |
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE |
|
||||
|
def self.all api |
||||
|
api.certificates.map { |cert| |
||||
|
Lxd::Certificate.new({api: api}.merge cert) |
||||
|
} |
||||
|
end |
||||
|
|
||||
request = Net::HTTP::Post.new(uri.request_uri) |
|
||||
request.body = { |
|
||||
:type => 'client', |
|
||||
:name => 'foo', |
|
||||
:password => '[where to get this from....]' |
|
||||
}.to_json |
|
||||
response = http.request(request) |
|
||||
|
def add password=nil, name='lex-deeit' |
||||
|
data = Hash.new |
||||
|
data[:type] = @type if @type else 'client' |
||||
|
data[:name] = name |
||||
|
data[:password] = password if password |
||||
|
data[:certificate] = @certificate if @certificate |
||||
|
|
||||
response.code |
|
||||
|
@api.add_certificate data |
||||
end |
end |
||||
end |
end |
||||
# vim: set ts=2 sw=2: |
# vim: set ts=2 sw=2: |
||||
@ -0,0 +1,15 @@ |
|||||
|
class Lxd::Config |
||||
|
include ActiveModel::Model |
||||
|
|
||||
|
attr_accessor :api, :api_extensions, :api_status, :api_version, :auth, |
||||
|
:config, :environment, :public |
||||
|
|
||||
|
def self.get api |
||||
|
Lxd::Config.new({api: api}.merge api.config) |
||||
|
end |
||||
|
|
||||
|
def save |
||||
|
@api.config = @config |
||||
|
end |
||||
|
end |
||||
|
# vim: set ts=2 sw=2: |
||||
@ -0,0 +1,50 @@ |
|||||
|
class Lxd::Connection |
||||
|
attr_reader :con, :host, :port |
||||
|
|
||||
|
""" |
||||
|
/1.0 |
||||
|
/1.0/certificates |
||||
|
/1.0/certificates/<fingerprint> |
||||
|
/1.0/containers |
||||
|
/1.0/containers/<name> |
||||
|
/1.0/containers/<name>/exec |
||||
|
/1.0/containers/<name>/files |
||||
|
/1.0/containers/<name>/snapshots |
||||
|
/1.0/containers/<name>/snapshots/<name> |
||||
|
/1.0/containers/<name>/state |
||||
|
/1.0/containers/<name>/logs |
||||
|
/1.0/containers/<name>/logs/<logfile> |
||||
|
/1.0/events |
||||
|
/1.0/images |
||||
|
/1.0/images/<fingerprint> |
||||
|
/1.0/images/<fingerprint>/export |
||||
|
/1.0/images/aliases |
||||
|
/1.0/images/aliases/<name> |
||||
|
/1.0/networks |
||||
|
/1.0/networks/<name> |
||||
|
/1.0/operations |
||||
|
/1.0/operations/<uuid> |
||||
|
/1.0/operations/<uuid>/wait |
||||
|
/1.0/operations/<uuid>/websocket |
||||
|
/1.0/profiles |
||||
|
/1.0/profiles/<name> |
||||
|
""" |
||||
|
|
||||
|
def initialize host, certificate |
||||
|
uri = URI.parse host.uri |
||||
|
@host = uri.host |
||||
|
@port = uri.port |
||||
|
@con = Net::HTTP.new @host, @port |
||||
|
@con.use_ssl = true |
||||
|
@con.cert = OpenSSL::X509::Certificate.new certificate.cert |
||||
|
@con.key = OpenSSL::PKey::EC.new certificate.key |
||||
|
@con.verify_mode = OpenSSL::SSL:VERIFY_NONE |
||||
|
end |
||||
|
|
||||
|
def call |
||||
|
if not @api_version |
||||
|
@con.request(Net::HTTP::Get.new '/') |
||||
|
versions |
||||
|
end |
||||
|
end |
||||
|
# vim: set et ts=2 sw=2: |
||||
@ -1,23 +0,0 @@ |
|||||
class Lxd::Server |
|
||||
include ActiveModel::Model |
|
||||
|
|
||||
attr_accessor :api_extensions, :api_status, :api_version, :auth, :config, |
|
||||
:environment, :public |
|
||||
|
|
||||
def self.by_host(host, certificate) |
|
||||
all = Array.new; |
|
||||
|
|
||||
uri = URI.parse(host.uri + '/1.0') |
|
||||
http = Net::HTTP.new(uri.host, uri.port) |
|
||||
http.use_ssl = true |
|
||||
http.cert = OpenSSL::X509::Certificate.new(certificate.cert) |
|
||||
http.key = OpenSSL::PKey::RSA.new(certificate.key) |
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE |
|
||||
|
|
||||
request = Net::HTTP::Get.new(uri.request_uri) |
|
||||
response = http.request(request) |
|
||||
|
|
||||
Lxd::Server.new(JSON.parse(response.body)['metadata']) |
|
||||
end |
|
||||
end |
|
||||
# vim: set ts=2 sw=2: |
|
||||
@ -1,11 +1,11 @@ |
|||||
<h1>Dashboard#index</h1> |
<h1>Dashboard#index</h1> |
||||
<p><%= @lxd_host.class %></p> |
<p><%= @lxd_host.class %></p> |
||||
<p><%= @cert.class %></p> |
<p><%= @cert.class %></p> |
||||
<p><%= @lxd.class %></p> |
|
||||
<p><%= @lxd.api_extensions.inspect %></p> |
|
||||
<p><%= @lxd.api_status %></p> |
|
||||
<p><%= @lxd.api_version %></p> |
|
||||
<p><%= @lxd.auth %></p> |
|
||||
<p><%= @lxd.config.inspect %></p> |
|
||||
<p><%= @lxd.environment.inspect %></p> |
|
||||
<p><%= @lxd.public %></p> |
|
||||
|
<p><%= @lxd_config.class %></p> |
||||
|
<p><%= @lxd_config.api_extensions.inspect %></p> |
||||
|
<p><%= @lxd_config.api_status %></p> |
||||
|
<p><%= @lxd_config.api_version %></p> |
||||
|
<p><%= @lxd_config.auth %></p> |
||||
|
<p><%= @lxd_config.config.inspect %></p> |
||||
|
<p><%= @lxd_config.environment.inspect %></p> |
||||
|
<p><%= @lxd_config.public %></p> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue