Browse Source

Start some real code...

master
Georg Hopp 10 years ago
parent
commit
c496fc34ea
  1. 37
      add-host-workflow.md
  2. 4
      app/controllers/application_controller.rb
  3. 11
      app/controllers/dashboard_controller.rb
  4. 11
      app/models/certificate.rb
  5. 45
      app/models/lxd/api.rb
  6. 54
      app/models/lxd/api/v1_0.rb
  7. 29
      app/models/lxd/certificate.rb
  8. 15
      app/models/lxd/config.rb
  9. 50
      app/models/lxd/connection.rb
  10. 23
      app/models/lxd/server.rb
  11. 16
      app/views/dashboard/index.html.erb

37
add-host-workflow.md

@ -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.

4
app/controllers/application_controller.rb

@ -2,4 +2,8 @@ class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception. # Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead. # For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception protect_from_forgery with: :exception
def check_cert
end
end end
# vim: set et ts=2 sw=2:

11
app/controllers/dashboard_controller.rb

@ -2,11 +2,14 @@ class DashboardController < ApplicationController
def index def index
@lxd_host = LxdHost.find(1) @lxd_host = LxdHost.find(1)
@cert = Certificate.find(1) @cert = Certificate.find(1)
@lxd = Lxd::Server.by_host @lxd_host, @cert
@api = Lxd::API.get @lxd_host, @cert
@lxd_config = Lxd::Config.get @api
if @lxd.auth == 'untrusted'
Lxd::Certificate.new.save(@lxd_host, @cert)
@lxd = Lxd::Server.by_host @lxd_host, @cert
if @lxd_config.auth == 'untrusted'
# Here the controller has to ask for the password
cert = Lxd::Certificate.new api: @api
cert.save 'xxxxxxxxxx'
@lxd_config = Lxd::Config.get @api
end end
end end
end end

11
app/models/certificate.rb

@ -3,7 +3,7 @@ require 'digest/md5'
class Certificate < ActiveRecord::Base class Certificate < ActiveRecord::Base
def key def key
OpenSSL::PKey::RSA.new read_attribute(:key) if read_attribute(:key)
OpenSSL::PKey::EC.new read_attribute(:key) if read_attribute(:key)
end end
def cert def cert
@ -11,11 +11,16 @@ class Certificate < ActiveRecord::Base
end end
def key_fpr def key_fpr
Digest::SHA1.hexdigest(key.to_der).upcase
Digest::SHA256.hexdigest(key.to_der).upcase
end end
def cert_fpr def cert_fpr
Digest::SHA1.hexdigest(cert.to_der).upcase
Digest::SHA256.hexdigest(cert.to_der).upcase
end
private
def _key
end end
end end
# vim: set et ts=2 sw=2: # vim: set et ts=2 sw=2:

45
app/models/lxd/api.rb

@ -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:

54
app/models/lxd/api/v1_0.rb

@ -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:

29
app/models/lxd/certificate.rb

@ -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:

15
app/models/lxd/config.rb

@ -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:

50
app/models/lxd/connection.rb

@ -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:

23
app/models/lxd/server.rb

@ -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:

16
app/views/dashboard/index.html.erb

@ -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>
Loading…
Cancel
Save