Class: Visor::Meta::Backends::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/meta/backends/base.rb

Overview

This is the Base super class for all Backends. Each new backend inherits from Base, which contains the model and all validations for the images metadata.

Implementing a new backend is as simple as create a new backend class which inherits from Base and them implement the specific methods for querying the underlying database.

Direct Known Subclasses

MongoDB, MySQL

Constant Summary collapse

MANDATORY =

Keys validation

Mandatory attributes

[:name, :architecture]
READONLY =

Read-only attributes

[:_id, :uri, :created_at, :updated_at, :accessed_at, :access_count]
OPTIONAL =

Optional attributes

[:owner, :status, :size, :checksum, :access, :type, :format,
:uploaded_at, :store, :location, :kernel, :ramdisk]
ALL =

All attributes

MANDATORY + OPTIONAL + READONLY
ARCHITECTURE =

Values validation

Architecture options

%w[i386 x86_64]
ACCESS =

Access options

%w[public private]
FORMAT =

Possible disk formats

%w[iso vhd vdi vmdk ami aki ari]
TYPE =

Possible types

%w[kernel ramdisk machine]
STATUS =

Possible status

%w[locked uploading error available]
STORE =

Possible storage

%w[s3 cumulus walrus hdfs lcs http file]
BRIEF =

Presentation options

Brief attributes used to return only brief information about images.

[:_id, :name, :architecture, :type, :format, :store, :size]
DETAIL_EXC =

Attributes to exclude from get public images requests, allowing to show other custom attributes.

[:accessed_at, :access_count]
FILTERS =

Valid parameters to filter results from requests query, add sort parameter and sort direction.

ALL + [:sort, :dir]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Base

Initializes a Backend instance.

Parameters:

  • [Hash] (Hash)

    a customizable set of options

  • opts (Hash)

    a customizable set of options

Options Hash (opts):

  • :host (String)

    The host address.

  • :port (Integer)

    The port to be used.

  • :db (String)

    The wanted database.

  • :user (String)

    The username to be authenticate db access.

  • :password (String)

    The password to be authenticate db access.

  • :conn (Object)

    The connection pool to access database.



60
61
62
63
64
65
66
67
# File 'lib/meta/backends/base.rb', line 60

def initialize(opts)
  @host     = opts[:host]
  @port     = opts[:port]
  @db       = opts[:db]
  @user     = opts[:user]
  @password = opts[:password]
  @conn     = opts[:conn]
end

Instance Attribute Details

#connObject (readonly)

Returns the value of attribute conn.



47
48
49
# File 'lib/meta/backends/base.rb', line 47

def conn
  @conn
end

#dbObject (readonly)

Returns the value of attribute db.



47
48
49
# File 'lib/meta/backends/base.rb', line 47

def db
  @db
end

#hostObject (readonly)

Returns the value of attribute host.



47
48
49
# File 'lib/meta/backends/base.rb', line 47

def host
  @host
end

#passwordObject (readonly)

Returns the value of attribute password.



47
48
49
# File 'lib/meta/backends/base.rb', line 47

def password
  @password
end

#portObject (readonly)

Returns the value of attribute port.



47
48
49
# File 'lib/meta/backends/base.rb', line 47

def port
  @port
end

#userObject (readonly)

Returns the value of attribute user.



47
48
49
# File 'lib/meta/backends/base.rb', line 47

def user
  @user
end

Instance Method Details

#build_uri(id, vis_address = nil) ⇒ String

Build an URI for the given image _id based on VISOR Image System configuration.

Parameters:

  • id (String)

    The _id of the image.

Returns:

  • (String)

    The generated URI.



158
159
160
161
162
163
164
# File 'lib/meta/backends/base.rb', line 158

def build_uri(id, vis_address = nil)
  if vis_address.nil?
    conf = Visor::Common::Config.load_config :visor_image
    vis_address = "#{conf[:bind_host]}:#{conf[:bind_port]}"
  end
  "http://#{vis_address}/images/#{id}"
end

#deserialize_others(meta) ⇒ Object

Deserialize with JSON and decapsulate additional (not on the table schema) image attributes from the others schema field.

This is used for SQL Backends, as they are not schema free.

Examples:

Instantiate a client with default values:

# So this:
{name: "example", access: "public", others: "{\"extra_key\":\"value\",\"another\":\"value\"}"}"}
# becomes this:
{name: 'example', access: 'public', extra_key: 'value', another: 'value'}

Parameters:

  • meta (Hash)

    The image metadata.



201
202
203
204
205
206
# File 'lib/meta/backends/base.rb', line 201

def deserialize_others(meta)
  if meta[:others]
    others = meta.delete :others
    meta.merge! JSON.parse(others, symbolize_names: true)
  end
end

#serialize_others(meta) ⇒ Object

Serializes with JSON and encapsulate additional (not on the table schema) image attributes on the others schema field.

This is used for SQL Backends, as they are not schema free.

Examples:

Instantiate a client with default values:

# So this:
{name: 'example', access: 'public', extra_key: 'value', another: 'value'}
# becomes this:
{name: "example", access: "public", others: "{\"extra_key\":\"value\",\"another\":\"value\"}"}"}

Parameters:

  • meta (Hash)

    The image metadata.



179
180
181
182
183
184
185
186
# File 'lib/meta/backends/base.rb', line 179

def serialize_others(meta)
  other_keys = meta.keys - ALL
  unless other_keys.empty?
    others = {}
    other_keys.each { |key| others[key] = meta.delete(key) }
    meta.merge!(others: others.to_json)
  end
end

#set_protected_post(meta, opts = {}) ⇒ Hash

Set protected fields value from a post operation. Being them the _id, uri, owner, size, access, status and created_at.

Parameters:

  • meta (Hash)

    The image metadata.

  • [Hash] (Hash)

    a customizable set of options

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :owner (String) — default: Nil

    The image owner.

  • :size (String) — default: Nil

    The image file size.

Returns:

  • (Hash)

    The image metadata filled with protected fields values.



133
134
135
136
137
138
139
140
# File 'lib/meta/backends/base.rb', line 133

def set_protected_post(meta, opts = {})
  owner, size, vis_address = opts[:owner], opts[:size], opts[:vis_address]
  meta.merge!(_id: SecureRandom.uuid)
  meta.merge!(access: 'public') unless meta[:access]
  meta.merge!(owner: owner) if owner
  meta.merge!(size: size) if size
  meta.merge!(created_at: Time.now, uri: build_uri(meta[:_id], vis_address), status: 'locked')
end

#set_protected_put(meta) ⇒ Hash

Set protected fields value from a get operation.

Parameters:

  • meta (Hash)

    The image metadata update.

Returns:

  • (Hash)

    The image metadata update with protected fields set.



148
149
150
# File 'lib/meta/backends/base.rb', line 148

def set_protected_put(meta)
  meta.merge!(updated_at: Time.now)
end

#string_time_or_hash?(v) ⇒ true, false

Verifies if a given object is a String, a Time or a Hash.

Parameters:

  • v (Object)

    The input value.

Returns:

  • (true, false)

    If the provided value is or not a String, a Time or a Hash.



214
215
216
# File 'lib/meta/backends/base.rb', line 214

def string_time_or_hash?(v)
  v.is_a?(String) or v.is_a?(Time) or v.is_a?(Hash)
end

#to_sql_insert(h) ⇒ String

Generates a compatible SQL INSERT string from a hash.

Parameters:

  • h (Hash)

    The input hash.

Returns:

  • (String)

    A string as “(k, k1) VALUES (‘v’, ‘v1’)”, only Strings Times or Hashes values are surrounded with ‘<value>’.



247
248
249
250
# File 'lib/meta/backends/base.rb', line 247

def to_sql_insert(h)
  surround = h.values.map { |v| string_time_or_hash?(v) ? "'#{v}'" : v }
  %W{(#{h.keys.join(', ')}) (#{surround.join(', ')})}
end

#to_sql_update(h) ⇒ String

Generates a compatible SQL UPDATE string from a hash.

Parameters:

  • h (Hash)

    The input hash.

Returns:

  • (String)

    A string as “k=‘v’, k1=‘v1’”, only Strings Times or Hashes values are surrounded with ‘<value>’.



236
237
238
# File 'lib/meta/backends/base.rb', line 236

def to_sql_update(h)
  h.map { |k, v| string_time_or_hash?(v) ? "#{k}='#{v}'" : "#{k}=#{v}" }.join(', ')
end

#to_sql_where(h) ⇒ String

Generates a compatible SQL WHERE string from a hash.

Parameters:

  • h (Hash)

    The input hash.

Returns:

  • (String)

    A string as “k=‘v’ AND k1=‘v1’”, only Strings Times or Hashes values are surrounded with ‘<value>’.



225
226
227
# File 'lib/meta/backends/base.rb', line 225

def to_sql_where(h)
  h.map { |k, v| string_time_or_hash?(v) ? "#{k}='#{v}'" : "#{k}=#{v}" }.join(' AND ')
end

#validate_data_post(meta) ⇒ Object

Validates the image metadata for a post operation, based on possible keys and values.

@raise If some of the metadata fields do not respect the

possible values, contains any read-only or misses any mandatory field.

Parameters:

  • meta (Hash)

    The image metadata.



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/meta/backends/base.rb', line 76

def validate_data_post(meta)
  meta.assert_exclusion_keys(READONLY)
  meta.assert_inclusion_keys(MANDATORY)

  meta.assert_valid_values_for(:architecture, ARCHITECTURE)
  meta.assert_valid_values_for(:access, ACCESS)
  meta.assert_valid_values_for(:format, FORMAT)
  meta.assert_valid_values_for(:type, TYPE)
  meta.assert_valid_values_for(:store, STORE)

  assert_ramdisk_and_kernel(meta)
end

#validate_data_put(meta) ⇒ Object

Validates the image metadata for a put operation, based on possible keys and values.

@raise If some of the metadata fields do not respect the

possible values, contains any read-only or misses any mandatory field.

Parameters:

  • meta (Hash)

    The image metadata.



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/meta/backends/base.rb', line 96

def validate_data_put(meta)
  meta.assert_exclusion_keys(READONLY)

  meta.assert_valid_values_for(:architecture, ARCHITECTURE)
  meta.assert_valid_values_for(:access, ACCESS)
  meta.assert_valid_values_for(:format, FORMAT)
  meta.assert_valid_values_for(:type, TYPE)
  meta.assert_valid_values_for(:store, STORE)

  assert_ramdisk_and_kernel(meta)
end

#validate_query_filters(filters) ⇒ Object

Validates that incoming query filters fields are valid.

@raise If some of the query filter fields do not respect the

possible values.

Parameters:

  • filters (Hash)

    The image metadata filters comming from a GET request.



115
116
117
118
119
# File 'lib/meta/backends/base.rb', line 115

def validate_query_filters(filters)
  filters.symbolize_keys!
  filters.assert_valid_keys(FILTERS)

end