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 |
|||
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 |
|||
# 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> |
|||
<p><%= @lxd_host.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