deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfoj...@redhat.com
Subject [PATCH core] EC2: Added initial support for CloudWatch via new Metric collection
Date Wed, 18 Jan 2012 13:27:00 GMT
From: Michal Fojtik <mfojtik@redhat.com>


Signed-off-by: Michal fojtik <mfojtik@redhat.com>
---
 server/config/drivers/ec2.yaml                  |    8 ++++
 server/lib/deltacloud/drivers/ec2/ec2_driver.rb |   51 ++++++++++++++++++++++-
 server/lib/deltacloud/models.rb                 |    1 +
 server/lib/deltacloud/models/metric.rb          |   40 ++++++++++++++++++
 server/lib/deltacloud/server.rb                 |   15 +++++++
 server/views/metrics/index.xml.haml             |    4 ++
 server/views/metrics/show.xml.haml              |   13 ++++++
 7 files changed, 131 insertions(+), 1 deletions(-)
 create mode 100644 server/lib/deltacloud/models/metric.rb
 create mode 100644 server/views/metrics/index.xml.haml
 create mode 100644 server/views/metrics/show.xml.haml

diff --git a/server/config/drivers/ec2.yaml b/server/config/drivers/ec2.yaml
index 3fa92d6..f56c66c 100644
--- a/server/config/drivers/ec2.yaml
+++ b/server/config/drivers/ec2.yaml
@@ -25,4 +25,12 @@
       eu-west-1: ec2.eu-west-1.amazonaws.com
       us-east-1: ec2.us-east-1.amazonaws.com
       sa-east-1: ec2.sa-east-1.amazonaws.com
+    mon:
+      us-west-1: monitoring.us-west-1.amazonaws.com
+      us-west-2: monitoring.us-west-2.amazonaws.com
+      ap-southeast-1: monitoring.ap-southeast-1.amazonaws.com
+      ap-northeast-1: monitoring.ap-northeast-1.amazonaws.com
+      eu-west-1: monitoring.eu-west-1.amazonaws.com
+      us-east-1: monitoring.us-east-1.amazonaws.com
+      sa-east-1: monitoring.sa-east-1.amazonaws.com
   :name: EC2
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index f899ea1..1ff79dd 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -34,7 +34,7 @@ module Deltacloud
 
         def supported_collections
 
-          DEFAULT_COLLECTIONS + [ :keys, :buckets, :load_balancers, :addresses, :firewalls
]
+          DEFAULT_COLLECTIONS + [ :keys, :buckets, :load_balancers, :addresses, :firewalls,
:metrics ]
         end
 
         feature :instances, :user_data
@@ -270,6 +270,36 @@ module Deltacloud
 
         alias :stop_instance :destroy_instance
 
+        def metrics(credentials, opts={})
+          cw = new_client(credentials, :mon)
+          metrics_arr = []
+          cw.list_metrics( :namespace => 'AWS/EC2' ).each do |metric|
+            if metrics_arr.any? { |m| m.id == metric[:value] }
+              i = metrics_arr.index { |m| m.id == metric[:value] }
+              metrics_arr[i] = metrics_arr[i].add_property(metric[:measure_name])
+            else
+              metrics_arr << convert_metric(metric)
+            end
+          end
+          metrics_arr.reject! { |m| m.unknown? }
+          filter_on(metrics_arr, :id, opts)
+        end
+
+        def metric(credentials, opts={})
+          cw = new_client(credentials, :mon)
+          m = metrics(credentials, :id => opts[:id])
+          return [] if m.empty?
+          m = m.first
+          # Get statistics from last 1 hour
+          start_time = (Time.now - 3600).utc.iso8601.to_s
+          end_time = Time.now.utc.iso8601.to_s
+          m.properties.each do |p|
+            p.values = cw.get_metric_statistics(p.name,  ['Minimum', 'Maximum', 'Average'],
+                        start_time, end_time, metric_unit_for(p.name), { m.entity => opts[:id]})
+          end
+          m
+        end
+
         def keys(credentials, opts={})
           ec2 = new_client(credentials)
           opts ||= {}
@@ -721,6 +751,7 @@ module Deltacloud
                     when :elb then Aws::Elb
                     when :ec2 then Aws::Ec2
                     when :s3 then Aws::S3
+                    when :mon then Aws::Mon
                   end
           klass.new(credentials.user, credentials.password, {:server => endpoint_for_service(type),
:connection_mode => :per_thread})
         end
@@ -945,6 +976,24 @@ module Deltacloud
                       }  )
         end
 
+        def metric_unit_for(name)
+          case name
+            when /Bytes/ then 'Bytes'
+            when /Ops/ then 'Count'
+            when /Count/ then 'Count'
+            when /Utilization/ then 'Percent'
+            when /Network/ then 'Bytes'
+            else 'None'
+          end
+        end
+
+        def convert_metric(metric)
+          Metric.new(
+            :id => metric[:value],
+            :entity => metric[:name] || :unknown,
+          ).add_property(metric[:measure_name])
+        end
+
         def convert_state(ec2_state)
           case ec2_state
             when "terminated"
diff --git a/server/lib/deltacloud/models.rb b/server/lib/deltacloud/models.rb
index a794192..af02520 100644
--- a/server/lib/deltacloud/models.rb
+++ b/server/lib/deltacloud/models.rb
@@ -30,3 +30,4 @@ require 'deltacloud/models/load_balancer'
 require 'deltacloud/models/firewall'
 require 'deltacloud/models/firewall_rule'
 require 'deltacloud/models/provider'
+require 'deltacloud/models/metric'
diff --git a/server/lib/deltacloud/models/metric.rb b/server/lib/deltacloud/models/metric.rb
new file mode 100644
index 0000000..42edaaf
--- /dev/null
+++ b/server/lib/deltacloud/models/metric.rb
@@ -0,0 +1,40 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+class Metric < BaseModel
+
+  attr_accessor :entity
+  attr_accessor :properties
+
+  def unknown?
+    true if self.entity == :unknown
+  end
+
+  def add_property(name, values=nil)
+    self.properties ||= []
+    return self if self.properties.any? { |p| p.name == name }
+    self.properties << Property.new(name, values)
+    self
+  end
+
+  class Property
+    attr_accessor :name, :values
+
+    def initialize(name, values=nil)
+      @name, @values = name, values
+    end
+  end
+
+end
diff --git a/server/lib/deltacloud/server.rb b/server/lib/deltacloud/server.rb
index db742d6..e1badaa 100644
--- a/server/lib/deltacloud/server.rb
+++ b/server/lib/deltacloud/server.rb
@@ -538,6 +538,21 @@ END
   end
 end
 
+collection :metrics do
+
+  operation :index do
+    with_capability :metrics
+    control { filter_all(:metrics) }
+  end
+
+  operation :show do
+    with_capability :metrics
+    param :id,  :string,  :required
+    control { show :metric }
+  end
+
+end
+
 collection :hardware_profiles do
   description <<END
  A hardware profile represents a configuration of resources upon which a
diff --git a/server/views/metrics/index.xml.haml b/server/views/metrics/index.xml.haml
new file mode 100644
index 0000000..a3b3d0d
--- /dev/null
+++ b/server/views/metrics/index.xml.haml
@@ -0,0 +1,4 @@
+!!!XML
+%metrics
+  - @elements.each do |c|
+    = haml :'metrics/show', :locals => { :@metric => c, :partial => true }
diff --git a/server/views/metrics/show.xml.haml b/server/views/metrics/show.xml.haml
new file mode 100644
index 0000000..55b96d2
--- /dev/null
+++ b/server/views/metrics/show.xml.haml
@@ -0,0 +1,13 @@
+- unless defined?(partial)
+  !!! XML
+%metric{ :href => metric_url(@metric.id), :id => @metric.id }
+  %properties
+    - @metric.properties.each do |p|
+      %property
+        %name=p.name
+        - if p.values
+          - p.values.each do |value|
+            %value{ :timestamp => value[:timestamp], :unit => value[:unit]}
+              %minimum=value[:minimum]
+              %maximum=value[:maximum]
+              %average=value[:average]
-- 
1.7.4.4


Mime
View raw message