1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00
Conflicts:
	lib/fog/compute.rb
	lib/fog/providers.rb
This commit is contained in:
Sean Handley 2012-06-22 10:07:19 +01:00
commit b8d57724ae
812 changed files with 20454 additions and 9521 deletions

1
.gitignore vendored
View file

@ -9,6 +9,7 @@
bin/*
!bin/fog
!bin/rdoc
.fog
coverage
doc/*
docs/_site/*

87
.irbrc Normal file
View file

@ -0,0 +1,87 @@
## This is primarily used for easier testing and development or
# usage of Fog.
#
# How to use:
# 1. Add this at the end of your `.irbrc` in your home directory.
#
# @working_directory = Dir.pwd
# @local_irbrc = File.join(@working_directory, '.irbrc')
#
# if @working_directory != ENV['HOME']
# load @local_irbrc if File.exists?(@local_irbrc)
# end
#
# remove_instance_variable(:@working_directory)
# remove_instance_variable(:@local_irbrc)
#
# 2. Inside the Fog execute `bundle exec irb`
#
require 'fog'
class ConnectionManager < Hash
def [](key)
$connection_manager_previous_key = key
super(key)
end
def []=(key, value)
$connection_manager_previous_key = key
super(key, value)
end
end
def connections
return @connections if @connections
@connections = ConnectionManager.new
end
def connection
connections[$connection_manager_previous_key]
end
def connect_openstack(username, password, tenant = nil, url = 'http://192.168.27.100:35357/')
parameters = {
:provider => 'openstack',
:openstack_api_key => password,
:openstack_username => username,
:openstack_auth_url => "#{url}v2.0/tokens"
}
parameters.merge!(:openstack_tenant => tenant) if tenant
identity = Fog::Identity.new(parameters)
compute = Fog::Compute.new(parameters)
volume = Fog::Volume.new(parameters)
image = Fog::Image.new(parameters)
connections[username.to_sym] = {
:identity => identity,
:compute => compute ,
:image => image
}
end
def connect(parameters)
connections_count = connections.count
connections[connections_count] = Hash.new
set_service(connections_count, Fog::Identity, parameters)
set_service(connections_count, Fog::Compute , parameters)
set_service(connections_count, Fog::Storage , parameters)
set_service(connections_count, Fog::Volume , parameters)
set_service(connections_count, Fog::Image , parameters)
set_service(connections_count, Fog::DNS , parameters)
set_service(connections_count, Fog::CDN , parameters)
connection
end
def set_service(connections_count, type, parameters)
service_symbol = type.to_s.split('::').last.downcase.to_sym
connections[connections_count].merge!({
service_symbol => type.new(parameters)
})
rescue
# Service not available
end

View file

@ -85,7 +85,7 @@
<!--[if lt IE 7 ]>
<script src="public/js/libs/dd_belatedpng.js"></script>
<script src="public/js/libs/dd_belatedpng.min.js"></script>
<script> DD_belatedPNG.fix('img, .png_bg'); </script>
<![endif]-->

View file

@ -20,8 +20,8 @@ Now you'll need to <a href="https://aws-portal.amazon.com/gp/aws/developer/subsc
# create a connection to the service
cdn = Fog::CDN.new({
:provider => 'AWS',
:aws_access_key_id => AWS_ACCESS_KEY_ID,
:aws_secret_access_key => AWS_SECRET_ACCESS_KEY
:aws_access_key_id => YOUR_AWS_ACCESS_KEY_ID,
:aws_secret_access_key => YOUR_AWS_SECRET_ACCESS_KEY
}
## Setting Up Your CDN

View file

@ -27,8 +27,8 @@ First, create a connection with your new account:
# create a connection
connection = Fog::Compute.new({
:provider => 'AWS',
:aws_secret_access_key => YOUR_SECRET_ACCESS_KEY,
:aws_access_key_id => YOUR_SECRET_ACCESS_KEY_ID
:aws_access_key_id => YOUR_AWS_ACCESS_KEY_ID,
:aws_secret_access_key => YOUR_AWS_SECRET_ACCESS_KEY
})
With that in hand we are ready to start making EC2 calls!

View file

@ -70,8 +70,8 @@ If you already have an account with another service you can just as easily use t
dns = Fog::DNS.new({
:provider => 'AWS',
:aws_access_key_id => AWS_ACCESS_KEY_ID,
:aws_secret_access_key => AWS_SECRET_ACCESS_KEY
:aws_access_key_id => YOUR_AWS_ACCESS_KEY_ID,
:aws_secret_access_key => YOUR_AWS_SECRET_ACCESS_KEY
})
## Go Forth and Resolve

302
docs/public/js/libs/dd_belatedpng.js Executable file → Normal file

File diff suppressed because one or more lines are too long

13
docs/public/js/libs/dd_belatedpng.min.js vendored Executable file

File diff suppressed because one or more lines are too long

892
docs/public/js/libs/modernizr-1.6.js vendored Normal file
View file

@ -0,0 +1,892 @@
/*!
* Modernizr v1.6
* http://www.modernizr.com
*
* Developed by:
* - Faruk Ates http://farukat.es/
* - Paul Irish http://paulirish.com/
*
* Copyright (c) 2009-2010
* Dual-licensed under the BSD or MIT licenses.
* http://www.modernizr.com/license/
*/
/*
* Modernizr is a script that detects native CSS3 and HTML5 features
* available in the current UA and provides an object containing all
* features with a true/false value, depending on whether the UA has
* native support for it or not.
*
* Modernizr will also add classes to the <html> element of the page,
* one for each feature it detects. If the UA supports it, a class
* like "cssgradients" will be added. If not, the class name will be
* "no-cssgradients". This allows for simple if-conditionals in your
* CSS, giving you fine control over the look & feel of your website.
*
* @author Faruk Ates
* @author Paul Irish
* @copyright (c) 2009-2010 Faruk Ates.
* @contributor Ben Alman
*/
window.Modernizr = (function(window,doc,undefined){
var version = '1.6',
ret = {},
/**
* !! DEPRECATED !!
*
* enableHTML5 is a private property for advanced use only. If enabled,
* it will make Modernizr.init() run through a brief while() loop in
* which it will create all HTML5 elements in the DOM to allow for
* styling them in Internet Explorer, which does not recognize any
* non-HTML4 elements unless created in the DOM this way.
*
* enableHTML5 is ON by default.
*
* The enableHTML5 toggle option is DEPRECATED as per 1.6, and will be
* replaced in 2.0 in lieu of the modular, configurable nature of 2.0.
*/
enableHTML5 = true,
docElement = doc.documentElement,
/**
* Create our "modernizr" element that we do most feature tests on.
*/
mod = 'modernizr',
m = doc.createElement( mod ),
m_style = m.style,
/**
* Create the input element for various Web Forms feature tests.
*/
f = doc.createElement( 'input' ),
smile = ':)',
tostring = Object.prototype.toString,
// List of property values to set for css tests. See ticket #21
prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '),
// Following spec is to expose vendor-specific style properties as:
// elem.style.WebkitBorderRadius
// and the following would be incorrect:
// elem.style.webkitBorderRadius
// Webkit ghosts their properties in lowercase but Opera & Moz do not.
// Microsoft foregoes prefixes entirely <= IE8, but appears to
// use a lowercase `ms` instead of the correct `Ms` in IE9
// More here: http://github.com/Modernizr/Modernizr/issues/issue/21
domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
ns = {'svg': 'http://www.w3.org/2000/svg'},
tests = {},
inputs = {},
attrs = {},
classes = [],
featurename, // used in testing loop
// todo: consider using http://javascript.nwbox.com/CSSSupport/css-support.js instead
testMediaQuery = function(mq){
var st = document.createElement('style'),
div = doc.createElement('div'),
ret;
st.textContent = mq + '{#modernizr{height:3px}}';
(doc.head || doc.getElementsByTagName('head')[0]).appendChild(st);
div.id = 'modernizr';
docElement.appendChild(div);
ret = div.offsetHeight === 3;
st.parentNode.removeChild(st);
div.parentNode.removeChild(div);
return !!ret;
},
/**
* isEventSupported determines if a given element supports the given event
* function from http://yura.thinkweb2.com/isEventSupported/
*/
isEventSupported = (function(){
var TAGNAMES = {
'select':'input','change':'input',
'submit':'form','reset':'form',
'error':'img','load':'img','abort':'img'
};
function isEventSupported(eventName, element) {
element = element || document.createElement(TAGNAMES[eventName] || 'div');
eventName = 'on' + eventName;
// When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
var isSupported = (eventName in element);
if (!isSupported) {
// If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
if (!element.setAttribute) {
element = document.createElement('div');
}
if (element.setAttribute && element.removeAttribute) {
element.setAttribute(eventName, '');
isSupported = typeof element[eventName] == 'function';
// If property was created, "remove it" (by setting value to `undefined`)
if (typeof element[eventName] != 'undefined') {
element[eventName] = undefined;
}
element.removeAttribute(eventName);
}
}
element = null;
return isSupported;
}
return isEventSupported;
})();
// hasOwnProperty shim by kangax needed for Safari 2.0 support
var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
if (typeof _hasOwnProperty !== 'undefined' && typeof _hasOwnProperty.call !== 'undefined') {
hasOwnProperty = function (object, property) {
return _hasOwnProperty.call(object, property);
};
}
else {
hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
return ((property in object) && typeof object.constructor.prototype[property] === 'undefined');
};
}
/**
* set_css applies given styles to the Modernizr DOM node.
*/
function set_css( str ) {
m_style.cssText = str;
}
/**
* set_css_all extrapolates all vendor-specific css strings.
*/
function set_css_all( str1, str2 ) {
return set_css(prefixes.join(str1 + ';') + ( str2 || '' ));
}
/**
* contains returns a boolean for if substr is found within str.
*/
function contains( str, substr ) {
return (''+str).indexOf( substr ) !== -1;
}
/**
* test_props is a generic CSS / DOM property test; if a browser supports
* a certain property, it won't return undefined for it.
* A supported CSS property returns empty string when its not yet set.
*/
function test_props( props, callback ) {
for ( var i in props ) {
if ( m_style[ props[i] ] !== undefined && ( !callback || callback( props[i], m ) ) ) {
return true;
}
}
}
/**
* test_props_all tests a list of DOM properties we want to check against.
* We specify literally ALL possible (known and/or likely) properties on
* the element including the non-vendor prefixed one, for forward-
* compatibility.
*/
function test_props_all( prop, callback ) {
var uc_prop = prop.charAt(0).toUpperCase() + prop.substr(1),
props = (prop + ' ' + domPrefixes.join(uc_prop + ' ') + uc_prop).split(' ');
return !!test_props( props, callback );
}
/**
* Tests
*/
tests['flexbox'] = function() {
/**
* set_prefixed_value_css sets the property of a specified element
* adding vendor prefixes to the VALUE of the property.
* @param {Element} element
* @param {string} property The property name. This will not be prefixed.
* @param {string} value The value of the property. This WILL be prefixed.
* @param {string=} extra Additional CSS to append unmodified to the end of
* the CSS string.
*/
function set_prefixed_value_css(element, property, value, extra) {
property += ':';
element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || '');
}
/**
* set_prefixed_property_css sets the property of a specified element
* adding vendor prefixes to the NAME of the property.
* @param {Element} element
* @param {string} property The property name. This WILL be prefixed.
* @param {string} value The value of the property. This will not be prefixed.
* @param {string=} extra Additional CSS to append unmodified to the end of
* the CSS string.
*/
function set_prefixed_property_css(element, property, value, extra) {
element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || '');
}
var c = doc.createElement('div'),
elem = doc.createElement('div');
set_prefixed_value_css(c, 'display', 'box', 'width:42px;padding:0;');
set_prefixed_property_css(elem, 'box-flex', '1', 'width:10px;');
c.appendChild(elem);
docElement.appendChild(c);
var ret = elem.offsetWidth === 42;
c.removeChild(elem);
docElement.removeChild(c);
return ret;
};
// On the S60 and BB Storm, getContext exists, but always returns undefined
// http://github.com/Modernizr/Modernizr/issues/issue/97/
tests['canvas'] = function() {
var elem = doc.createElement( 'canvas' );
return !!(elem.getContext && elem.getContext('2d'));
};
tests['canvastext'] = function() {
return !!(ret['canvas'] && typeof doc.createElement( 'canvas' ).getContext('2d').fillText == 'function');
};
tests['webgl'] = function(){
var elem = doc.createElement( 'canvas' );
try {
if (elem.getContext('webgl')){ return true; }
} catch(e){ }
try {
if (elem.getContext('experimental-webgl')){ return true; }
} catch(e){ }
return false;
};
/*
* The Modernizr.touch test only indicates if the browser supports
* touch events, which does not necessarily reflect a touchscreen
* device, as evidenced by tablets running Windows 7 or, alas,
* the Palm Pre / WebOS (touch) phones.
*
* Additionally, Chrome (desktop) used to lie about its support on this,
* but that has since been rectified: http://crbug.com/36415
*
* We also test for Firefox 4 Multitouch Support.
*
* For more info, see: http://modernizr.github.com/Modernizr/touch.html
*/
tests['touch'] = function() {
return ('ontouchstart' in window) || testMediaQuery('@media ('+prefixes.join('touch-enabled),(')+'modernizr)');
};
/**
* geolocation tests for the new Geolocation API specification.
* This test is a standards compliant-only test; for more complete
* testing, including a Google Gears fallback, please see:
* http://code.google.com/p/geo-location-javascript/
* or view a fallback solution using google's geo API:
* http://gist.github.com/366184
*/
tests['geolocation'] = function() {
return !!navigator.geolocation;
};
// Per 1.6:
// This used to be Modernizr.crosswindowmessaging but the longer
// name has been deprecated in favor of a shorter and property-matching one.
// The old API is still available in 1.6, but as of 2.0 will throw a warning,
// and in the first release thereafter disappear entirely.
tests['postmessage'] = function() {
return !!window.postMessage;
};
// Web SQL database detection is tricky:
// In chrome incognito mode, openDatabase is truthy, but using it will
// throw an exception: http://crbug.com/42380
// We can create a dummy database, but there is no way to delete it afterwards.
// Meanwhile, Safari users can get prompted on any database creation.
// If they do, any page with Modernizr will give them a prompt:
// http://github.com/Modernizr/Modernizr/issues/closed#issue/113
// We have chosen to allow the Chrome incognito false positive, so that Modernizr
// doesn't litter the web with these test databases. As a developer, you'll have
// to account for this gotcha yourself.
tests['websqldatabase'] = function() {
var result = !!window.openDatabase;
/*
if (result){
try {
result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4);
} catch(e) {
}
}
*/
return result;
};
// Vendors have inconsistent prefixing with the experimental Indexed DB:
// - Firefox is shipping indexedDB in FF4 as moz_indexedDB
// - Webkit's implementation is accessible through webkitIndexedDB
// We test both styles.
tests['indexedDB'] = function(){
for (var i = -1, len = domPrefixes.length; ++i < len; ){
var prefix = domPrefixes[i].toLowerCase();
if (window[prefix + '_indexedDB'] || window[prefix + 'IndexedDB']){
return true;
}
}
return false;
};
// documentMode logic from YUI to filter out IE8 Compat Mode
// which false positives.
tests['hashchange'] = function() {
return isEventSupported('hashchange', window) && ( document.documentMode === undefined || document.documentMode > 7 );
};
// Per 1.6:
// This used to be Modernizr.historymanagement but the longer
// name has been deprecated in favor of a shorter and property-matching one.
// The old API is still available in 1.6, but as of 2.0 will throw a warning,
// and in the first release thereafter disappear entirely.
tests['history'] = function() {
return !!(window.history && history.pushState);
};
tests['draganddrop'] = function() {
return isEventSupported('drag') &&
isEventSupported('dragstart') &&
isEventSupported('dragenter') &&
isEventSupported('dragover') &&
isEventSupported('dragleave') &&
isEventSupported('dragend') &&
isEventSupported('drop');
};
tests['websockets'] = function(){
return ('WebSocket' in window);
};
// http://css-tricks.com/rgba-browser-support/
tests['rgba'] = function() {
// Set an rgba() color and check the returned value
set_css( 'background-color:rgba(150,255,150,.5)' );
return contains( m_style.backgroundColor, 'rgba' );
};
tests['hsla'] = function() {
// Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
// except IE9 who retains it as hsla
set_css('background-color:hsla(120,40%,100%,.5)' );
return contains( m_style.backgroundColor, 'rgba' ) || contains( m_style.backgroundColor, 'hsla' );
};
tests['multiplebgs'] = function() {
// Setting multiple images AND a color on the background shorthand property
// and then querying the style.background property value for the number of
// occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
set_css( 'background:url(//:),url(//:),red url(//:)' );
// If the UA supports multiple backgrounds, there should be three occurrences
// of the string "url(" in the return value for elem_style.background
return new RegExp("(url\\s*\\(.*?){3}").test(m_style.background);
};
// In testing support for a given CSS property, it's legit to test:
// elem.style[styleName] !== undefined
// If the property is supported it will return an empty string,
// if unsupported it will return undefined.
// We'll take advantage of this quick test and skip setting a style
// on our modernizr element, but instead just testing undefined vs
// empty string.
// The legacy set_css_all calls will remain in the source
// (however, commented) for clarity, yet functionally they are
// no longer needed.
tests['backgroundsize'] = function() {
return test_props_all( 'backgroundSize' );
};
tests['borderimage'] = function() {
// set_css_all( 'border-image:url(m.png) 1 1 stretch' );
return test_props_all( 'borderImage' );
};
// Super comprehensive table about all the unique implementations of
// border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
tests['borderradius'] = function() {
// set_css_all( 'border-radius:10px' );
return test_props_all( 'borderRadius', '', function( prop ) {
return contains( prop, 'orderRadius' );
});
};
tests['boxshadow'] = function() {
// set_css_all( 'box-shadow:#000 1px 1px 3px' );
return test_props_all( 'boxShadow' );
};
// Note: FF3.0 will false positive on this test
tests['textshadow'] = function(){
return doc.createElement('div').style.textShadow === '';
};
tests['opacity'] = function() {
// Browsers that actually have CSS Opacity implemented have done so
// according to spec, which means their return values are within the
// range of [0.0,1.0] - including the leading zero.
set_css_all( 'opacity:.5' );
return contains( m_style.opacity, '0.5' );
};
tests['cssanimations'] = function() {
// set_css_all( 'animation:"animate" 2s ease 2', 'position:relative' );
return test_props_all( 'animationName' );
};
tests['csscolumns'] = function() {
// set_css_all( 'column-count:3' );
return test_props_all( 'columnCount' );
};
tests['cssgradients'] = function() {
/**
* For CSS Gradients syntax, please see:
* http://webkit.org/blog/175/introducing-css-gradients/
* https://developer.mozilla.org/en/CSS/-moz-linear-gradient
* https://developer.mozilla.org/en/CSS/-moz-radial-gradient
* http://dev.w3.org/csswg/css3-images/#gradients-
*/
var str1 = 'background-image:',
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
str3 = 'linear-gradient(left top,#9f9, white);';
set_css(
(str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0,-str1.length)
);
return contains( m_style.backgroundImage, 'gradient' );
};
tests['cssreflections'] = function() {
// set_css_all( 'box-reflect:right 1px' );
return test_props_all( 'boxReflect' );
};
tests['csstransforms'] = function() {
// set_css_all( 'transform:rotate(3deg)' );
return !!test_props([ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ]);
};
tests['csstransforms3d'] = function() {
// set_css_all( 'perspective:500' );
var ret = !!test_props([ 'perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective' ]);
// Webkits 3D transforms are passed off to the browser's own graphics renderer.
// It works fine in Safari on Leopard and Snow Leopard, but not in Chrome (yet?).
// As a result, Webkit typically recognizes the syntax but will sometimes throw a false
// positive, thus we must do a more thorough check:
if (ret){
// Webkit allows this media query to succeed only if the feature is enabled.
// "@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }"
ret = testMediaQuery('@media ('+prefixes.join('transform-3d),(')+'modernizr)');
}
return ret;
};
tests['csstransitions'] = function() {
// set_css_all( 'transition:all .5s linear' );
return test_props_all( 'transitionProperty' );
};
// @font-face detection routine by Diego Perini
// http://javascript.nwbox.com/CSSSupport/
tests['fontface'] = function(){
var
sheet,
head = doc.head || doc.getElementsByTagName('head')[0] || docElement,
style = doc.createElement("style"),
impl = doc.implementation || { hasFeature: function() { return false; } };
style.type = 'text/css';
head.insertBefore(style, head.firstChild);
sheet = style.sheet || style.styleSheet;
// removing it crashes IE browsers
//head.removeChild(style);
var supportAtRule = impl.hasFeature('CSS2', '') ?
function(rule) {
if (!(sheet && rule)) return false;
var result = false;
try {
sheet.insertRule(rule, 0);
result = !(/unknown/i).test(sheet.cssRules[0].cssText);
sheet.deleteRule(sheet.cssRules.length - 1);
} catch(e) { }
return result;
} :
function(rule) {
if (!(sheet && rule)) return false;
sheet.cssText = rule;
return sheet.cssText.length !== 0 && !(/unknown/i).test(sheet.cssText) &&
sheet.cssText
.replace(/\r+|\n+/g, '')
.indexOf(rule.split(' ')[0]) === 0;
};
// DEPRECATED - allow for a callback
ret._fontfaceready = function(fn){
fn(ret.fontface);
};
return supportAtRule('@font-face { font-family: "font"; src: "font.ttf"; }');
};
// These tests evaluate support of the video/audio elements, as well as
// testing what types of content they support.
//
// We're using the Boolean constructor here, so that we can extend the value
// e.g. Modernizr.video // true
// Modernizr.video.ogg // 'probably'
//
// Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
// thx to NielsLeenheer and zcorpan
// Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string.
// Modernizr does not normalize for that.
tests['video'] = function() {
var elem = doc.createElement('video'),
bool = !!elem.canPlayType;
if (bool){
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"');
// Workaround required for IE9, which doesn't report video support without audio codec specified.
// bug 599718 @ msft connect
var h264 = 'video/mp4; codecs="avc1.42E01E';
bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
}
return bool;
};
tests['audio'] = function() {
var elem = doc.createElement('audio'),
bool = !!elem.canPlayType;
if (bool){
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"');
bool.mp3 = elem.canPlayType('audio/mpeg;');
// Mimetypes accepted:
// https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
// http://bit.ly/iphoneoscodecs
bool.wav = elem.canPlayType('audio/wav; codecs="1"');
bool.m4a = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;');
}
return bool;
};
// Both localStorage and sessionStorage are
// tested via the `in` operator because otherwise Firefox will
// throw an error: https://bugzilla.mozilla.org/show_bug.cgi?id=365772
// if cookies are disabled
// They require try/catch because of possible firefox configuration:
// http://github.com/Modernizr/Modernizr/issues#issue/92
// FWIW miller device resolves to [object Storage] in all supporting browsers
// except for IE who does [object Object]
// IE8 Compat mode supports these features completely:
// http://www.quirksmode.org/dom/html5.html
tests['localstorage'] = function() {
try {
return ('localStorage' in window) && window.localStorage !== null;
} catch(e) {
return false;
}
};
tests['sessionstorage'] = function() {
try {
return ('sessionStorage' in window) && window.sessionStorage !== null;
} catch(e){
return false;
}
};
tests['webWorkers'] = function () {
return !!window.Worker;
};
tests['applicationcache'] = function() {
return !!window.applicationCache;
};
// Thanks to Erik Dahlstrom
tests['svg'] = function(){
return !!doc.createElementNS && !!doc.createElementNS(ns.svg, "svg").createSVGRect;
};
tests['inlinesvg'] = function() {
var div = document.createElement('div');
div.innerHTML = '<svg/>';
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
};
// Thanks to F1lt3r and lucideer
// http://github.com/Modernizr/Modernizr/issues#issue/35
tests['smil'] = function(){
return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS(ns.svg,'animate')));
};
tests['svgclippaths'] = function(){
// Possibly returns a false positive in Safari 3.2?
return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS(ns.svg,'clipPath')));
};
// input features and input types go directly onto the ret object, bypassing the tests loop.
// Hold this guy to execute in a moment.
function webforms(){
// Run through HTML5's new input attributes to see if the UA understands any.
// We're using f which is the <input> element created early on
// Mike Taylr has created a comprehensive resource for testing these attributes
// when applied to all input types:
// http://miketaylr.com/code/input-type-attr.html
// spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
ret['input'] = (function(props) {
for (var i = 0,len=props.length;i<len;i++) {
attrs[ props[i] ] = !!(props[i] in f);
}
return attrs;
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
// Run through HTML5's new input types to see if the UA understands any.
// This is put behind the tests runloop because it doesn't return a
// true/false like all the other tests; instead, it returns an object
// containing each input type with its corresponding true/false value
// Big thanks to @miketaylr for the html5 forms expertise. http://miketaylr.com/
ret['inputtypes'] = (function(props) {
for (var i = 0, bool, len=props.length ; i < len ; i++) {
f.setAttribute('type', props[i]);
bool = f.type !== 'text';
// Chrome likes to falsely purport support, so we feed it a textual value;
// if that doesnt succeed then we know there's a custom UI
if (bool){
f.value = smile;
if (/^range$/.test(f.type) && f.style.WebkitAppearance !== undefined){
docElement.appendChild(f);
var defaultView = doc.defaultView;
// Safari 2-4 allows the smiley as a value, despite making a slider
bool = defaultView.getComputedStyle &&
defaultView.getComputedStyle(f, null).WebkitAppearance !== 'textfield' &&
// Mobile android web browser has false positive, so must
// check the height to see if the widget is actually there.
(f.offsetHeight !== 0);
docElement.removeChild(f);
} else if (/^(search|tel)$/.test(f.type)){
// Spec doesnt define any special parsing or detectable UI
// behaviors so we pass these through as true
// Interestingly, opera fails the earlier test, so it doesn't
// even make it here.
} else if (/^(url|email)$/.test(f.type)) {
// Real url and email support comes with prebaked validation.
bool = f.checkValidity && f.checkValidity() === false;
} else {
// If the upgraded input compontent rejects the :) text, we got a winner
bool = f.value != smile;
}
}
inputs[ props[i] ] = !!bool;
}
return inputs;
})('search tel url email datetime date month week time datetime-local number range color'.split(' '));
}
// End of test definitions
// Run through all tests and detect their support in the current UA.
// todo: hypothetically we could be doing an array of tests and use a basic loop here.
for ( var feature in tests ) {
if ( hasOwnProperty( tests, feature ) ) {
// run the test, throw the return value into the Modernizr,
// then based on that boolean, define an appropriate className
// and push it into an array of classes we'll join later.
featurename = feature.toLowerCase();
ret[ featurename ] = tests[ feature ]();
classes.push( ( ret[ featurename ] ? '' : 'no-' ) + featurename );
}
}
// input tests need to run.
if (!ret.input) webforms();
// Per 1.6: deprecated API is still accesible for now:
ret.crosswindowmessaging = ret.postmessage;
ret.historymanagement = ret.history;
/**
* Addtest allows the user to define their own feature tests
* the result will be added onto the Modernizr object,
* as well as an appropriate className set on the html element
*
* @param feature - String naming the feature
* @param test - Function returning true if feature is supported, false if not
*/
ret.addTest = function (feature, test) {
feature = feature.toLowerCase();
if (ret[ feature ]) {
return; // quit if you're trying to overwrite an existing test
}
test = !!(test());
docElement.className += ' ' + (test ? '' : 'no-') + feature;
ret[ feature ] = test;
return ret; // allow chaining.
};
/**
* Reset m.style.cssText to nothing to reduce memory footprint.
*/
set_css( '' );
m = f = null;
// Enable HTML 5 elements for styling in IE.
// fyi: jscript version does not reflect trident version
// therefore ie9 in ie7 mode will still have a jScript v.9
if ( enableHTML5 && window.attachEvent && (function(){ var elem = doc.createElement("div");
elem.innerHTML = "<elem></elem>";
return elem.childNodes.length !== 1; })()) {
// iepp v1.6 by @jon_neal : code.google.com/p/ie-print-protector
(function(f,l){var j="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",n=j.split("|"),k=n.length,g=new RegExp("<(/*)("+j+")","gi"),h=new RegExp("\\b("+j+")\\b(?!.*[;}])","gi"),m=l.createDocumentFragment(),d=l.documentElement,i=d.firstChild,b=l.createElement("style"),e=l.createElement("body");b.media="all";function c(p){var o=-1;while(++o<k){p.createElement(n[o])}}c(l);c(m);function a(t,s){var r=t.length,q=-1,o,p=[];while(++q<r){o=t[q];s=o.media||s;p.push(a(o.imports,s));p.push(o.cssText)}return p.join("")}f.attachEvent("onbeforeprint",function(){var r=-1;while(++r<k){var o=l.getElementsByTagName(n[r]),q=o.length,p=-1;while(++p<q){if(o[p].className.indexOf("iepp_")<0){o[p].className+=" iepp_"+n[r]}}}i.insertBefore(b,i.firstChild);b.styleSheet.cssText=a(l.styleSheets,"all").replace(h,".iepp_$1");m.appendChild(l.body);d.appendChild(e);e.innerHTML=m.firstChild.innerHTML.replace(g,"<$1bdo")});f.attachEvent("onafterprint",function(){e.innerHTML="";d.removeChild(e);i.removeChild(b);d.appendChild(m.firstChild)})})(this,document);
}
// Assign private properties to the return object with prefix
ret._enableHTML5 = enableHTML5;
ret._version = version;
// Remove "no-js" class from <html> element, if it exists:
docElement.className=docElement.className.replace(/\bno-js\b/,'') + ' js';
// Add the new classes to the <html> element.
docElement.className += ' ' + classes.join( ' ' );
return ret;
})(this,this.document);

File diff suppressed because it is too large Load diff

View file

@ -35,8 +35,8 @@ First, create a connection with your new account:
# create a connection
connection = Fog::Storage.new({
:provider => 'AWS',
:aws_access_key_id => YOUR_SECRET_ACCESS_KEY_ID,
:aws_secret_access_key => YOUR_SECRET_ACCESS_KEY
:aws_access_key_id => YOUR_AWS_ACCESS_KEY_ID,
:aws_secret_access_key => YOUR_AWS_SECRET_ACCESS_KEY
})
# First, a place to contain the glorious details

View file

@ -42,7 +42,7 @@ Gem::Specification.new do |s|
## List your runtime dependencies here. Runtime dependencies are those
## that are needed for an end user to actually USE your code.
s.add_dependency('builder')
s.add_dependency('excon', '~>0.13.0')
s.add_dependency('excon', '~>0.14.0')
s.add_dependency('formatador', '~>0.2.0')
s.add_dependency('multi_json', '~>1.0')
s.add_dependency('mime-types')
@ -63,6 +63,7 @@ Gem::Specification.new do |s|
s.add_development_dependency('shindo', '~>0.3.4')
s.add_development_dependency('virtualbox', '~>0.9.1')
s.add_development_dependency('fission')
s.add_development_dependency('pry')
# s.add_development_dependency('ruby-libvirt','~>0.4.0')
s.files = `git ls-files`.split("\n")

View file

@ -13,6 +13,9 @@ require 'fog/providers'
require 'fog/terremark'
require 'fog/compute'
require 'fog/identity'
require 'fog/image'
require 'fog/volume'
require 'fog/cdn'
require 'fog/dns'
require 'fog/storage'

View file

@ -1,4 +1,4 @@
require(File.expand_path(File.join(File.dirname(__FILE__), 'core')))
require 'fog/core'
module Fog
module AWS
@ -237,6 +237,32 @@ module Fog
def self.network_interface_id
"eni-#{Fog::Mock.random_hex(8)}"
end
def self.internet_gateway_id
"igw-#{Fog::Mock.random_hex(8)}"
end
def self.dhcp_options_id
"dopt-#{Fog::Mock.random_hex(8)}"
end
def self.vpc_id
"vpc-#{Fog::Mock.random_hex(8)}"
end
def self.subnet_id
"subnet-#{Fog::Mock.random_hex(8)}"
end
def self.zone_id
"zone-#{Fog::Mock.random_hex(8)}"
end
def self.change_id
"change-#{Fog::Mock.random_hex(8)}"
end
def self.nameservers
[
'ns-2048.awsdns-64.com',
'ns-2049.awsdns-65.net',
'ns-2050.awsdns-66.org',
'ns-2051.awsdns-67.co.uk'
]
end
def self.key_id(length=21)
#Probably close enough

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -145,7 +145,6 @@ module Fog
def self.data
@data ||= Hash.new do |hash, region|
owner_id = Fog::AWS::Mock.owner_id
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:adjustment_types => [

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -109,15 +109,15 @@ module Fog
)
begin
response = @connection.request({
:body => body,
:expects => 200,
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
:idempotent => idempotent,
:host => @host,
:method => 'POST',
:parser => parser
})
@connection.request({
:body => body,
:expects => 200,
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
:idempotent => idempotent,
:host => @host,
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
if match = error.response.body.match(/<Code>(.*)<\/Code>[ \t\n]*<Message>(.*)<\/Message>/)
raise case match[1].split('.').last

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
require 'fog/cdn'
module Fog
@ -112,7 +112,7 @@ module Fog
def signature(params)
string_to_sign = params[:headers]['Date']
signed_string = @hmac.sign(string_to_sign)
signature = Base64.encode64(signed_string).chomp!
Base64.encode64(signed_string).chomp!
end
end
end

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -98,7 +98,7 @@ module Fog
}
)
response = @connection.request({
@connection.request({
:body => body,
:expects => 200,
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
require 'fog/compute'
module Fog
@ -11,10 +11,14 @@ module Fog
model_path 'fog/aws/models/compute'
model :address
collection :addresses
model :dhcp_options
collection :dhcp_options
model :flavor
collection :flavors
model :image
collection :images
model :internet_gateway
collection :internet_gateways
model :key_pair
collection :key_pairs
model :network_interface
@ -39,10 +43,14 @@ module Fog
request_path 'fog/aws/requests/compute'
request :allocate_address
request :associate_address
request :associate_dhcp_options
request :attach_network_interface
request :attach_internet_gateway
request :attach_volume
request :authorize_security_group_ingress
request :cancel_spot_instance_requests
request :create_dhcp_options
request :create_internet_gateway
request :create_image
request :create_key_pair
request :create_network_interface
@ -54,6 +62,8 @@ module Fog
request :create_tags
request :create_volume
request :create_vpc
request :delete_dhcp_options
request :delete_internet_gateway
request :delete_key_pair
request :delete_network_interface
request :delete_security_group
@ -67,8 +77,10 @@ module Fog
request :deregister_image
request :describe_addresses
request :describe_availability_zones
request :describe_dhcp_options
request :describe_images
request :describe_instances
request :describe_internet_gateways
request :describe_reserved_instances
request :describe_instance_status
request :describe_key_pairs
@ -88,6 +100,7 @@ module Fog
request :describe_volume_status
request :describe_vpcs
request :detach_network_interface
request :detach_internet_gateway
request :detach_volume
request :disassociate_address
request :get_console_output
@ -177,6 +190,7 @@ module Fog
:network_interfaces => {},
:snapshots => {},
:volumes => {},
:internet_gateways => {},
:tags => {},
:tag_sets => Hash.new do |tag_set_hash, resource_id|
tag_set_hash[resource_id] = {}
@ -278,6 +292,9 @@ module Fog
#
# ==== Returns
# * EC2 object with connection to aws.
attr_accessor :region
def initialize(options={})
require 'fog/core/parser'

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
require 'fog/dns'
module Fog
@ -29,7 +29,11 @@ module Fog
@data ||= Hash.new do |hash, region|
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:buckets => {}
:buckets => {},
:limits => {
:duplicate_domains => 5
},
:zones => {}
}
end
end
@ -111,7 +115,7 @@ module Fog
def signature(params)
string_to_sign = params[:headers]['Date']
signed_string = @hmac.sign(string_to_sign)
signature = Base64.encode64(signed_string).chomp!
Base64.encode64(signed_string).chomp!
end
end
end

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -9,7 +9,7 @@ module Fog
request_path 'fog/aws/requests/dynamodb'
request :batch_get_item
request :batch_put_item
request :batch_write_item
request :create_table
request :delete_item
request :delete_table
@ -106,12 +106,12 @@ module Fog
def request(params)
idempotent = params.delete(:idempotent)
now = Fog::Time.now
headers = {
'Content-Type' => 'application/x-amz-json-1.0',
'x-amz-date' => Fog::Time.now.to_date_header,
'x-amz-security-token' => @aws_session_token
}.merge(params[:headers])
headers['x-amzn-authorization'] = signed_authorization_header(params, headers)
response = @connection.request({

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -37,6 +37,9 @@ module Fog
request :register_instances_with_load_balancer
request :set_load_balancer_listener_ssl_certificate
request :set_load_balancer_policies_of_listener
request :attach_load_balancer_to_subnets
request :detach_load_balancer_from_subnets
request :apply_security_groups_to_load_balancer
model_path 'fog/aws/models/elb'
model :load_balancer
@ -145,11 +148,11 @@ module Fog
:host => @host,
:path => @path,
:port => @port,
:version => '2011-11-15'
:version => '2012-06-01'
}
)
response = @connection.request({
@connection.request({
:body => body,
:expects => 200,
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },

View file

@ -31,5 +31,436 @@ class Fog::AWS::ELB::Mock
"Description"=>""
}],
"PolicyTypeName"=>"PublicKeyPolicyType"
}]
},
{
"Description" => "Listener policy that defines the ciphers and protocols that will be accepted by the load balancer. This policy can be associated only with HTTPS/SSL listeners.",
"PolicyAttributeTypeDescriptions" => [{
"AttributeName"=>"Protocol-SSLv2",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EDH-DSS-DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-CAMELLIA128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DES-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-RC4-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-CAMELLIA128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"PSK-RC4-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"PSK-AES128-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-EDH-RSA-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"CAMELLIA128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-AES128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EDH-RSA-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-SEED-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-DES-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-CAMELLIA256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DES-CBC3-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-RC2-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EDH-DSS-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"PSK-AES256-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-AES256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"AES128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-SEED-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-CAMELLIA256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-RC4-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EDH-RSA-DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-DES-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"Protocol-TLSv1",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"PSK-3DES-EDE-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"SEED-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-CAMELLIA256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"IDEA-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"RC2-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-AES128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"RC4-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"AES256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"Protocol-SSLv3",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"EXP-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-AES128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-EDH-DSS-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-RC2-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-AES256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-DES-CBC3-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"EXP-RC2-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-ADH-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"CAMELLIA256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-CAMELLIA128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-ADH-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-AES256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-SEED-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
}],
"PolicyTypeName"=>"SSLNegotiationPolicyType"
}]
end

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -109,20 +109,8 @@ module Fog
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
if match = error.message.match(/<Code>(.*)<\/Code>[\s\\\w]+<Message>(.*)<\/Message>/m)
# case match[1].split('.').last
# when 'DBInstanceNotFound', 'DBParameterGroupNotFound', 'DBSnapshotNotFound', 'DBSecurityGroupNotFound'
# raise Fog::AWS::RDS::NotFound.slurp(error, match[2])
# when 'DBParameterGroupAlreadyExists'
# raise Fog::AWS::RDS::IdentifierTaken.slurp(error, match[2])
# else
# raise
# end
raise
else
raise
end
rescue Excon::Errors::HTTPStatusError
raise
end
response

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -55,6 +55,15 @@ module Fog
request :update_user
request :upload_server_certificate
request :upload_signing_certificate
model_path 'fog/aws/models/iam'
model :user
collection :users
model :policy
collection :policies
model :access_key
collection :access_keys
class Mock
def self.data

View file

@ -71,6 +71,16 @@ module Fog
reload
end
def swap_cnames(source)
requires :name
connection.swap_environment_cnames({
'SourceEnvironmentName' => source.name,
'DestinationEnvironmentName' => name
})
source.reload
reload
end
# Return the version object for this environment
def version
requires :application_name, :version_label

View file

@ -0,0 +1,68 @@
require 'fog/core/model'
module Fog
module Compute
class AWS
class DhcpOption < Fog::Model
identity :id, :aliases => 'dhcpOptionsId'
attribute :dhcp_configuration_set, :aliases => 'dhcpConfigurationSet'
attribute :tag_set, :aliases => 'tagSet'
def initialize(attributes={})
super
end
# Associates an existing dhcp configration set with a VPC
#
# dhcp_option.attach(dopt-id, vpc-id)
#
# ==== Returns
#
# True or false depending on the result
#
def associate(vpc_id)
requires :id
connection.attach_dhcp_option(id, vpc_id)
#reload
end
# Removes an existing dhcp configuration set
#
# dhcp_option.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :id
connection.delete_dhcp_options(id)
true
end
# Create a dhcp configuration set
#
# >> g = AWS.dhcp_options.new()
# >> g.save
#
# == Returns:
#
# requestId and a dhcpOptions object
#
def save
requires :dhcp_configuration_set
data = connection.create_dhcp_options(dhcp_configuration_set).body['dhcpOptionsSet'].first
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
true
true
end
end
end
end
end

View file

@ -0,0 +1,91 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/dhcp_option'
module Fog
module Compute
class AWS
class DhcpOptions < Fog::Collection
attribute :filters
model Fog::Compute::AWS::DhcpOption
# Creates a new dhcp option
#
# AWS.dhcp_options.new
#
# ==== Returns
#
# Returns the details of the new DHCP options
#
#>> AWS.dhcp_options.new
#=> <Fog::Compute::AWS::DhcpOption
#id=nil,
#dhcp_configuration_set=nil,
#tag_set=nil
#>
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all DhcpOptions that have been created
#
# AWS.dhcp_options.all
#
# ==== Returns
#
# Returns an array of all DhcpOptions
#
#>> AWS.dhcp_options.all
#<Fog::Compute::AWS::DhcpOptions
#filters={}
#[
#<Fog::Compute::AWS::DhcpOption
#id="dopt-some-id",
#dhcp_configuration_set={"vpcId"=>"vpc-some-id", "state"=>"available"},
#tag_set={}
#>
#]
#>
#
def all(filters = filters)
unless filters.is_a?(Hash)
Fog::Logger.warning("all with #{filters.class} param is deprecated, use all('internet-gateway-id' => []) instead [light_black](#{caller.first})[/]")
filters = {'dhcp-options-id' => [*filters]}
end
self.filters = filters
data = connection.describe_dhcp_options(filters).body
load(data['dhcpOptionsSet'])
end
# Used to retrieve an DhcpOption
#
# You can run the following command to get the details:
# AWS.dhcp_options.get("dopt-12345678")
#
# ==== Returns
#
#>> AWS.dhcp_options.get("dopt-12345678")
#=> <Fog::Compute::AWS::DhcpOption
#id="dopt-12345678",
#dhcp_configuration_set={"vpcId"=>"vpc-12345678", "state"=>"available"},
#tag_set={}
#>
#
def get(dhcp_options_id)
if dhcp_options_id
self.class.new(:connection => connection).all('dhcp-options-id' => dhcp_options_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,81 @@
require 'fog/core/model'
module Fog
module Compute
class AWS
class InternetGateway < Fog::Model
identity :id, :aliases => 'internetGatewayId'
attribute :attachment_set, :aliases => 'attachmentSet'
attribute :tag_set, :aliases => 'tagSet'
def initialize(attributes={})
super
end
# Attaches an existing internet gateway
#
# internet_gateway.attach(igw-id, vpc-id)
#
# ==== Returns
#
# True or false depending on the result
#
def attach(vpc_id)
requires :id
connection.attach_internet_gateway(id, vpc_id)
reload
end
# Detaches an existing internet gateway
#
# internet_gateway.detach(igw-id, vpc-id)
#
# ==== Returns
#
# True or false depending on the result
#
def detach(vpc_id)
requires :id
connection.detach_internet_gateway(id, vpc_id)
reload
end
# Removes an existing internet gateway
#
# internet_gateway.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :id
connection.delete_internet_gateway(id)
true
end
# Create an internet gateway
#
# >> g = AWS.internet_gateways.new()
# >> g.save
#
# == Returns:
#
# requestId and a internetGateway object
#
def save
data = connection.create_internet_gateway.body['internetGatewaySet'].first
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
true
true
end
end
end
end
end

View file

@ -0,0 +1,91 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/internet_gateway'
module Fog
module Compute
class AWS
class InternetGateways < Fog::Collection
attribute :filters
model Fog::Compute::AWS::InternetGateway
# Creates a new internet gateway
#
# AWS.internet_gateways.new
#
# ==== Returns
#
# Returns the details of the new InternetGateway
#
#>> AWS.internet_gateways.new
#=> <Fog::Compute::AWS::InternetGateway
#id=nil,
#attachment_set=nil,
#tag_set=nil
#>
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all InternetGateways that have been created
#
# AWS.internet_gateways.all
#
# ==== Returns
#
# Returns an array of all InternetGateways
#
#>> AWS.internet_gateways.all
#<Fog::Compute::AWS::InternetGateways
#filters={}
#[
#<Fog::Compute::AWS::InternetGateway
#id="igw-some-id",
#attachment_set={"vpcId"=>"vpc-some-id", "state"=>"available"},
#tag_set={}
#>
#]
#>
#
def all(filters = filters)
unless filters.is_a?(Hash)
Fog::Logger.warning("all with #{filters.class} param is deprecated, use all('internet-gateway-id' => []) instead [light_black](#{caller.first})[/]")
filters = {'internet-gateway-id' => [*filters]}
end
self.filters = filters
data = connection.describe_internet_gateways(filters).body
load(data['internetGatewaySet'])
end
# Used to retrieve an InternetGateway
#
# You can run the following command to get the details:
# AWS.internet_gateways.get("igw-12345678")
#
# ==== Returns
#
#>> AWS.internet_gateways.get("igw-12345678")
#=> <Fog::Compute::AWS::InternetGateway
#id="igw-12345678",
#attachment_set={"vpcId"=>"vpc-12345678", "state"=>"available"},
#tag_set={}
#>
#
def get(internet_gateway_id)
if internet_gateway_id
self.class.new(:connection => connection).all('internet-gateway-id' => internet_gateway_id).first
end
end
end
end
end
end

View file

@ -40,6 +40,8 @@ module Fog
#
def authorize_group_and_owner(group, owner = nil)
Fog::Logger.deprecation("authorize_group_and_ownder is deprecated, use authorize_port_range with :group option instead")
requires_one :name, :group_id
connection.authorize_security_group_ingress(
@ -62,6 +64,7 @@ module Fog
# options::
# A hash that can contain any of the following keys:
# :cidr_ip (defaults to "0.0.0.0/0")
# :group - ("account:group_name" or "account:group_id"), cannot be used with :cidr_ip
# :ip_protocol (defaults to "tcp")
#
# == Returns:
@ -81,21 +84,26 @@ module Fog
def authorize_port_range(range, options = {})
requires_one :name, :group_id
ip_permission = {
'FromPort' => range.min,
'ToPort' => range.max,
'IpProtocol' => options[:ip_protocol] || 'tcp'
}
if options[:group].nil?
ip_permission['IpRanges'] = [
{ 'CidrIp' => options[:cidr_ip] || '0.0.0.0/0' }
]
else
ip_permission['Groups'] = [
group_info(options[:group])
]
end
connection.authorize_security_group_ingress(
name,
'GroupId' => group_id,
'IpPermissions' => [
{
'FromPort' => range.min,
'ToPort' => range.max,
'IpProtocol' => options[:ip_protocol] || 'tcp',
'IpRanges' => [
{
'CidrIp' => options[:cidr_ip] || '0.0.0.0/0'
}
]
}
]
'IpPermissions' => [ ip_permission ]
)
end
@ -146,6 +154,8 @@ module Fog
#
def revoke_group_and_owner(group, owner = nil)
Fog::Logger.deprecation("revoke_group_and_owner is deprecated, use revoke_port_range with :group option instead")
requires_one :name, :group_id
connection.revoke_security_group_ingress(
@ -168,6 +178,7 @@ module Fog
# options::
# A hash that can contain any of the following keys:
# :cidr_ip (defaults to "0.0.0.0/0")
# :group - ("account:group_name" or "account:group_id"), cannot be used with :cidr_ip
# :ip_protocol (defaults to "tcp")
#
# == Returns:
@ -187,21 +198,26 @@ module Fog
def revoke_port_range(range, options = {})
requires_one :name, :group_id
ip_permission = {
'FromPort' => range.min,
'ToPort' => range.max,
'IpProtocol' => options[:ip_protocol] || 'tcp'
}
if options[:group].nil?
ip_permission['IpRanges'] = [
{ 'CidrIp' => options[:cidr_ip] || '0.0.0.0/0' }
]
else
ip_permission['Groups'] = [
group_info(options[:group])
]
end
connection.revoke_security_group_ingress(
name,
'GroupId' => group_id,
'IpPermissions' => [
{
'FromPort' => range.min,
'ToPort' => range.max,
'IpProtocol' => options[:ip_protocol] || 'tcp',
'IpRanges' => [
{
'CidrIp' => options[:cidr_ip] || '0.0.0.0/0'
}
]
}
]
'IpPermissions' => [ ip_permission ]
)
end
@ -224,6 +240,28 @@ module Fog
true
end
private
def group_info(group_str)
account, group = group_str.split(":")
if account.empty? || group.nil? || group.empty?
raise ArgumentError, "group must be specified in form of \"<account id>:<group name or id>\", #{group_str} given"
end
info = { 'UserId' => account }
if group.start_with?("sg-")
# we're dealing with a security group id
info['GroupId'] = group
else
# this has to be a security group name
info['GroupName'] = group
end
info
end
end
end

View file

@ -14,6 +14,7 @@ module Fog
attribute :ami_launch_index, :aliases => 'amiLaunchIndex'
attribute :availability_zone, :aliases => 'availabilityZone'
attribute :block_device_mapping, :aliases => 'blockDeviceMapping'
attribute :network_interfaces, :aliases => 'networkInterfaces'
attribute :client_token, :aliases => 'clientToken'
attribute :dns_name, :aliases => 'dnsName'
attribute :groups
@ -163,9 +164,10 @@ module Fog
}
options.delete_if {|key, value| value.nil?}
# If subnet is defined we are working on a virtual private cloud.
# subnet & security group cannot co-exist. I wish VPC just ignored
# the security group parameter instead, it would be much easier!
# If subnet is defined then this is a Virtual Private Cloud.
# subnet & security group cannot co-exist. Attempting to specify
# both subnet and groups will cause an error. Instead please make
# use of Security Group Ids when working in a VPC.
if subnet_id
options.delete('SecurityGroup')
else
@ -204,18 +206,8 @@ module Fog
end
# wait for aws to be ready
Timeout::timeout(360) do
begin
Timeout::timeout(8) do
Fog::SSH.new(public_ip_address, username, credentials.merge(:timeout => 4)).run('pwd')
end
rescue Errno::ECONNREFUSED
sleep(2)
retry
rescue Net::SSH::AuthenticationFailed, Timeout::Error
retry
end
end
wait_for { sshable? }
Fog::SSH.new(public_ip_address, username, credentials).run(commands)
end

View file

@ -65,7 +65,7 @@ module Fog
load(
data['reservationSet'].map do |reservation|
reservation['instancesSet'].map do |instance|
instance.merge(:groups => reservation['groupSet'])
instance.merge(:groups => reservation['groupSet'], :security_group_ids => reservation['groupIds'])
end
end.flatten
)

View file

@ -61,7 +61,7 @@ module Fog
end
spot_request.save
spot_request.wait_for { ready? }
spot_request.wait_for(Fog.timeout, interval=4) { ready? }
Fog.wait_for { server = connection.servers.get(spot_request.reload.instance_id) }
server = connection.servers.get(spot_request.instance_id)
if spot_request.tags

View file

@ -14,9 +14,17 @@ module Fog
attribute :source_group, :aliases => 'SourceSecurityGroup'
attribute :hosted_zone_name, :aliases => 'CanonicalHostedZoneName'
attribute :hosted_zone_name_id, :aliases => 'CanonicalHostedZoneNameID'
attribute :subnet_ids, :aliases => 'Subnets'
attribute :security_groups, :aliases => 'SecurityGroups'
attribute :scheme, :aliases => 'Scheme'
attribute :vpc_id, :aliases => 'VPCId'
def initialize(attributes={})
attributes[:availability_zones] ||= attributes['AvailabilityZones'] || %w(us-east-1a us-east-1b us-east-1c us-east-1d)
if attributes[:subnet_ids] ||= attributes['Subnets']
attributes[:availability_zones] ||= attributes['AvailabilityZones']
else
attributes[:availability_zones] ||= attributes['AvailabilityZones'] || %w(us-east-1a us-east-1b us-east-1c us-east-1d)
end
unless attributes['ListenerDescriptions']
new_listener = Fog::AWS::ELB::Listener.new
attributes['ListenerDescriptions'] = [{
@ -53,6 +61,24 @@ module Fog
data = connection.disable_availability_zones_for_load_balancer(zones, id).body['DisableAvailabilityZonesForLoadBalancerResult']
merge_attributes(data)
end
def attach_subnets(subnet_ids)
requires :id
data = connection.attach_load_balancer_to_subnets(subnet_ids, id).body['AttachLoadBalancerToSubnetsResult']
merge_attributes(data)
end
def detach_subnets(subnet_ids)
requires :id
data = connection.detach_load_balancer_from_subnets(subnet_ids, id).body['DetachLoadBalancerFromSubnetsResult']
merge_attributes(data)
end
def apply_security_groups(security_groups)
requires :id
data = connection.apply_security_groups_to_load_balancer(security_groups, id).body['ApplySecurityGroupsToLoadBalancerResult']
merge_attributes(data)
end
def instance_health
requires :id
@ -114,9 +140,15 @@ module Fog
def save
requires :id
requires :listeners
requires :availability_zones
connection.create_load_balancer(availability_zones, id, listeners.map{|l| l.to_params})
# with the VPC release, the ELB can have either availability zones or subnets
# if both are specified, the availability zones have preference
#requires :availability_zones
if (availability_zones || subnet_ids)
connection.create_load_balancer(availability_zones, id, listeners.map{|l| l.to_params}) if availability_zones
connection.create_load_balancer(nil, id, listeners.map{|l| l.to_params}, {:subnet_ids => subnet_ids, :security_groups => security_groups, :scheme => scheme}) if subnet_ids && !availability_zones
else
throw Fog::Errors::Error.new("No availability zones or subnet ids specified")
end
# reload instead of merge attributes b/c some attrs (like HealthCheck)
# may be set, but only the DNS name is returned in the create_load_balance

View file

@ -24,8 +24,10 @@ module Fog
end
def get(identity)
data = connection.describe_load_balancers('LoadBalancerNames' => identity).body['DescribeLoadBalancersResult']['LoadBalancerDescriptions'].first
new(data)
if identity
data = connection.describe_load_balancers('LoadBalancerNames' => identity).body['DescribeLoadBalancersResult']['LoadBalancerDescriptions'].first
new(data)
end
rescue Fog::AWS::ELB::NotFound
nil
end

View file

@ -0,0 +1,38 @@
require 'fog/core/model'
module Fog
module AWS
class IAM
class AccessKey < Fog::Model
identity :id, :aliases => 'AccessKeyId'
attribute :username, :aliases => 'UserName'
attribute :secret_access_key, :aliases => 'SecretAccessKey'
attribute :status, :aliases => 'Status'
def save
requires :username
data = connection.create_access_key('UserName'=> username).body["AccessKey"]
merge_attributes(data)
true
end
def destroy
requires :id
requires :username
connection.delete_access_key(id,'UserName'=> username)
true
end
def user
requires :username
connection.users.get(username)
end
end
end
end
end

View file

@ -0,0 +1,36 @@
require 'fog/core/collection'
require 'fog/aws/models/iam/access_key'
module Fog
module AWS
class IAM
class AccessKeys < Fog::Collection
model Fog::AWS::IAM::AccessKey
def initialize(attributes = {})
@username = attributes[:username]
raise ArgumentError.new("Can't get an access_key's user without a username") unless @username
super
end
def all
data = connection.list_access_keys('UserName'=> @username).body['AccessKeys']
# AWS response doesn't contain the UserName, this injects it
data.each {|access_key| access_key['UserName'] = @username }
load(data)
end
def get(identity)
self.all.select {|access_key| access_key.id == identity}.first
end
def new(attributes = {})
super({ :username => @username }.merge!(attributes))
end
end
end
end
end

View file

@ -0,0 +1,44 @@
require 'fog/core/collection'
require 'fog/aws/models/iam/policy'
module Fog
module AWS
class IAM
class Policies < Fog::Collection
model Fog::AWS::IAM::Policy
def initialize(attributes = {})
@username = attributes[:username]
raise ArgumentError.new("Can't get a policy's user without a username") unless @username
super
end
def all
# AWS method get_user_policy only returns an array of policy names, this is kind of useless,
# that's why it has to loop through the list to get the details of each element. I don't like it because it makes this method slow
policy_names = connection.list_user_policies(@username).body['PolicyNames'] # it returns an array
policies = []
policy_names.each do |policy_name|
policies << connection.get_user_policy(policy_name,@username).body['Policy']
end
load(policies) # data is an array of attribute hashes
end
def get(identity)
data = connection.get_user_policy(identity,@username).body['Policy']
new(data) # data is an attribute hash
rescue Fog::AWS::IAM::NotFound
nil
end
def new(attributes = {})
super({ :username => @username }.merge!(attributes))
end
end
end
end
end

View file

@ -0,0 +1,39 @@
require 'fog/core/model'
module Fog
module AWS
class IAM
class Policy < Fog::Model
identity :id, :aliases => 'PolicyName'
attribute :username, :aliases => 'UserName'
attribute :document, :aliases => 'PolicyDocument'
def save
requires :id
requires :username
requires :document
data = connection.put_user_policy(username, id, document).body
merge_attributes(data)
true
end
def destroy
requires :id
requires :username
connection.delete_user_policy(username, id)
true
end
def user
requires :username
connection.users.get(username)
end
end
end
end
end

View file

@ -0,0 +1,40 @@
require 'fog/core/model'
module Fog
module AWS
class IAM
class User < Fog::Model
identity :id, :aliases => 'UserName'
attribute :path, :aliases => 'Path'
attribute :arn, :aliases => 'Arn'
attribute :user_id, :aliases => 'UserId'
def save
requires :id
data = connection.create_user(id).body['User']
merge_attributes(data)
true
end
def destroy
requires :id
connection.delete_user(id)
true
end
def policies
requires :id
connection.policies(:username => id)
end
def access_keys
requires :id
connection.access_keys(:username => id)
end
end
end
end
end

View file

@ -0,0 +1,27 @@
require 'fog/core/collection'
require 'fog/aws/models/iam/user'
module Fog
module AWS
class IAM
class Users < Fog::Collection
model Fog::AWS::IAM::User
def all
data = connection.list_users.body['Users']
load(data) # data is an array of attribute hashes
end
def get(identity)
data = connection.get_user(identity).body['User']
new(data) # data is an attribute hash
rescue Fog::AWS::IAM::NotFound
nil
end
end
end
end
end

View file

@ -7,17 +7,23 @@ module Fog
class AWS
class Directory < Fog::Model
VALID_ACLS = ['private', 'public-read', 'public-read-write', 'authenticated-read']
# See http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html
INVALID_LOCATIONS = ['us-east-1']
attr_reader :acl
identity :key, :aliases => ['Name', 'name']
attribute :creation_date, :aliases => 'CreationDate'
def acl=(new_acl)
valid_acls = ['private', 'public-read', 'public-read-write', 'authenticated-read']
unless valid_acls.include?(new_acl)
raise ArgumentError.new("acl must be one of [#{valid_acls.join(', ')}]")
unless VALID_ACLS.include?(new_acl)
raise ArgumentError.new("acl must be one of [#{VALID_ACLS.join(', ')}]")
else
@acl = new_acl
end
@acl = new_acl
end
def destroy
@ -30,21 +36,19 @@ module Fog
def location
requires :key
data = connection.get_bucket_location(key)
data.body['LocationConstraint']
attributes[:location] || bucket_location || self.connection.region
end
def location=(new_location)
@location = new_location
if INVALID_LOCATIONS.include?(new_location)
raise ArgumentError, "location must not include any of #{INVALID_LOCATIONS.join(', ')}. See http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html"
else
merge_attributes(:location => new_location)
end
end
def files
@files ||= begin
Fog::Storage::AWS::Files.new(
:directory => self,
:connection => connection
)
end
@files ||= Fog::Storage::AWS::Files.new(:directory => self, :connection => connection)
end
def payer
@ -71,20 +75,11 @@ module Fog
end
def versions
@versions ||= begin
Fog::Storage::AWS::Versions.new(
:directory => self,
:connection => connection
)
end
@versions ||= Fog::Storage::AWS::Versions.new(:directory => self, :connection => connection)
end
def public=(new_public)
if new_public
@acl = 'public-read'
else
@acl = 'private'
end
self.acl = new_public ? 'public-read' : 'private'
new_public
end
@ -103,18 +98,27 @@ module Fog
def save
requires :key
options = {}
if @acl
options['x-amz-acl'] = @acl
end
lc = @location || self.connection.region
if lc != 'us-east-1' # us-east-1 is not valid: See http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html
options['LocationConstraint'] = lc
options['x-amz-acl'] = acl if acl
if location = attributes[:location] || (self.connection.region != 'us-east-1' && self.connection.region)
options['LocationConstraint'] = location
end
connection.put_bucket(key, options)
true
end
private
def bucket_location
data = connection.get_bucket_location(key)
data.body['LocationConstraint']
end
end
end

View file

@ -0,0 +1,24 @@
module Fog
module Parsers
module Compute
module AWS
class AssociateDhcpOptions < Fog::Parsers::Base
def end_element(name)
case name
when 'requestId'
@response[name] = value
when 'return'
if value == 'true'
@response[name] = true
else
@response[name] = false
end
end
end
end
end
end
end
end

View file

@ -0,0 +1,24 @@
module Fog
module Parsers
module Compute
module AWS
class AttachInternetGateway < Fog::Parsers::Base
def end_element(name)
case name
when 'requestId'
@response[name] = value
when 'return'
if value == 'true'
@response[name] = true
else
@response[name] = false
end
end
end
end
end
end
end
end

View file

@ -0,0 +1,75 @@
module Fog
module Parsers
module Compute
module AWS
class CreateDhcpOptions < Fog::Parsers::Base
def reset
@dhcp_options = { 'dhcpConfigurationSet' => {}, 'tagSet' => {} }
@response = { 'dhcpOptionsSet' => [] }
@tag = {}
@value_set = []
@dhcp_configuration = {}
end
def start_element(name, attrs = [])
super
case name
when 'tagSet'
@in_tag_set = true
when 'dhcpConfigurationSet'
@in_dhcp_configuration_set = true
when 'valueSet'
@in_value_set = true
end
end
def end_element(name)
if @in_tag_set
case name
when 'item'
@dhcp_options['tagSet'][@tag['key']] = @tag['value']
@tag = {}
when 'key', 'value'
@tag[name] = value
when 'tagSet'
@in_tag_set = false
end
elsif @in_dhcp_configuration_set
case name
when 'item'
unless @in_value_set
@dhcp_options['dhcpConfigurationSet'][@dhcp_configuration['key']] = @value_set
@value_set=[]
@dhcp_configuration = {}
end
when 'key', 'value'
if !@in_value_set
@dhcp_configuration[name] = value
else
@value_set << value
end
when 'valueSet'
@in_value_set = false
when 'dhcpConfigurationSet'
@in_dhcp_configuration_set = false
end
else
case name
when 'dhcpOptionsId'
@dhcp_options[name] = value
when 'dhcpOptions'
@response['dhcpOptionsSet'] << @dhcp_options
@dhcp_options = { 'tagSet' => {} }
@dhcp_options = { 'dhcpOptionsSet' => {} }
when 'requestId'
@response[name] = value
end
end
end
end
end
end
end
end

View file

@ -0,0 +1,65 @@
module Fog
module Parsers
module Compute
module AWS
class CreateInternetGateway < Fog::Parsers::Base
def reset
@internet_gateway = { 'attachmentSet' => {}, 'tagSet' => {} }
@response = { 'internetGatewaySet' => [] }
@tag = {}
@attachment = {}
end
def start_element(name, attrs = [])
super
case name
when 'tagSet'
@in_tag_set = true
when 'attachmentSet'
@in_attachment_set = true
end
end
def end_element(name)
if @in_tag_set
case name
when 'item'
@vpc['tagSet'][@tag['key']] = @tag['value']
@tag = {}
when 'key', 'value'
@tag[name] = value
when 'tagSet'
@in_tag_set = false
end
elsif @in_attachment_set
case name
when 'item'
@internet_gateway['attachmentSet'][@attachment['key']] = @attachment['value']
@attachment = {}
when 'key', 'value'
@attachment[name] = value
when 'attachmentSet'
@in_attachment_set = false
end
else
case name
when 'internetGatewayId'
@internet_gateway[name] = value
when 'internetGateway'
@response['internetGatewaySet'] << @internet_gateway
@internet_gateway = { 'tagSet' => {} }
@internet_gateway = { 'attachmentSet' => {} }
when 'requestId'
@response[name] = value
end
end
end
end
end
end
end
end

View file

@ -0,0 +1,24 @@
module Fog
module Parsers
module Compute
module AWS
class DeleteDhcpOptions < Fog::Parsers::Base
def end_element(name)
case name
when 'requestId'
@response[name] = value
when 'return'
if value == 'true'
@response[name] = true
else
@response[name] = false
end
end
end
end
end
end
end
end

View file

@ -0,0 +1,24 @@
module Fog
module Parsers
module Compute
module AWS
class DeleteInternetGateway < Fog::Parsers::Base
def end_element(name)
case name
when 'requestId'
@response[name] = value
when 'return'
if value == 'true'
@response[name] = true
else
@response[name] = false
end
end
end
end
end
end
end
end

View file

@ -0,0 +1,75 @@
module Fog
module Parsers
module Compute
module AWS
class DescribeDhcpOptions < Fog::Parsers::Base
def reset
@dhcp_options = { 'dhcpConfigurationSet' => {}, 'tagSet' => {} }
@response = { 'dhcpOptionsSet' => [] }
@tag = {}
@value_set = []
@dhcp_configuration = {}
end
def start_element(name, attrs = [])
super
case name
when 'tagSet'
@in_tag_set = true
when 'dhcpConfigurationSet'
@in_dhcp_configuration_set = true
when 'valueSet'
@in_value_set = true
end
end
def end_element(name)
if @in_tag_set
case name
when 'item'
@dhcp_options['tagSet'][@tag['key']] = @tag['value']
@tag = {}
when 'key', 'value'
@tag[name] = value
when 'tagSet'
@in_tag_set = false
end
elsif @in_dhcp_configuration_set
case name
when 'item'
unless @in_value_set
@dhcp_options['dhcpConfigurationSet'][@dhcp_configuration['key']] = @value_set
@value_set=[]
@dhcp_configuration = {}
end
when 'key', 'value'
if !@in_value_set
@dhcp_configuration[name] = value
else
@value_set << value
end
when 'valueSet'
@in_value_set = false
when 'dhcpConfigurationSet'
@in_dhcp_configuration_set = false
end
else
case name
when 'dhcpOptionsId'
@dhcp_options[name] = value
when 'item'
@response['dhcpOptionsSet'] << @dhcp_options
@dhcp_options = { 'tagSet' => {} }
@dhcp_options = { 'dhcpConfigurationSet' => {} }
when 'requestId'
@response[name] = value
end
end
end
end
end
end
end
end

View file

@ -7,10 +7,11 @@ module Fog
def reset
@block_device_mapping = {}
@network_interface = {}
@context = []
@contexts = ['blockDeviceMapping', 'groupSet', 'instancesSet', 'instanceState', 'networkInterfaceSet', 'placement', 'productCodes', 'stateReason', 'tagSet']
@instance = { 'blockDeviceMapping' => [], 'instanceState' => {}, 'monitoring' => {}, 'placement' => {}, 'productCodes' => [], 'stateReason' => {}, 'tagSet' => {} }
@reservation = { 'groupSet' => [], 'instancesSet' => [] }
@instance = { 'blockDeviceMapping' => [], 'networkInterfaces' => [], 'instanceState' => {}, 'monitoring' => {}, 'placement' => {}, 'productCodes' => [], 'stateReason' => {}, 'tagSet' => {} }
@reservation = { 'groupIds' => [], 'groupSet' => [], 'instancesSet' => [] }
@response = { 'reservationSet' => [] }
@tag = {}
end
@ -31,7 +32,7 @@ module Fog
when 'architecture', 'clientToken', 'dnsName', 'imageId',
'instanceId', 'instanceType', 'ipAddress', 'kernelId',
'keyName', 'platform', 'privateDnsName', 'privateIpAddress', 'ramdiskId',
'reason', 'rootDeviceType', 'subnetId', 'vpcId'
'reason', 'rootDeviceType'
@instance[name] = value
when 'attachTime'
@block_device_mapping[name] = Time.parse(value)
@ -43,10 +44,20 @@ module Fog
@block_device_mapping[name] = (value == 'true')
when 'deviceName', 'status', 'volumeId'
@block_device_mapping[name] = value
when 'subnetId', 'vpcId', 'ownerId', 'networkInterfaceId', 'attachmentId'
@network_interface[name] = value
@instance[name] = value
when 'groupId', 'groupName'
case @context.last
when 'groupSet'
@reservation['groupSet'] << value if @context.first != "instancesSet"
(name == 'groupName') ? current_key = 'groupSet' : current_key = 'groupIds'
case @context[-2]
when 'instancesSet'
@reservation[current_key] << value
when 'networkInterfaceSet'
@network_interface[current_key] ||= []
@network_interface[current_key] << value
end
when 'placement'
@instance['placement'][name] = value
end
@ -55,15 +66,18 @@ module Fog
when 'blockDeviceMapping'
@instance['blockDeviceMapping'] << @block_device_mapping
@block_device_mapping = {}
when 'networkInterfaceSet'
@instance['networkInterfaces'] << @network_interface
@network_interface = {}
when 'instancesSet'
@reservation['instancesSet'] << @instance
@instance = { 'blockDeviceMapping' => [], 'instanceState' => {}, 'monitoring' => {}, 'placement' => {}, 'productCodes' => [], 'stateReason' => {}, 'tagSet' => {} }
@instance = { 'blockDeviceMapping' => [], 'networkInterfaces' => [], 'instanceState' => {}, 'monitoring' => {}, 'placement' => {}, 'productCodes' => [], 'stateReason' => {}, 'tagSet' => {} }
when 'tagSet'
@instance['tagSet'][@tag['key']] = @tag['value']
@tag = {}
when nil
@response['reservationSet'] << @reservation
@reservation = { 'groupSet' => [], 'instancesSet' => [] }
@reservation = { 'groupIds' => [], 'groupSet' => [], 'instancesSet' => [] }
end
when 'key', 'value'
@tag[name] = value

View file

@ -0,0 +1,65 @@
module Fog
module Parsers
module Compute
module AWS
class DescribeInternetGateways < Fog::Parsers::Base
def reset
@internet_gateway = { 'attachmentSet' => {}, 'tagSet' => {} }
@response = { 'internetGatewaySet' => [] }
@tag = {}
@attachment = {}
end
def start_element(name, attrs = [])
super
case name
when 'tagSet'
@in_tag_set = true
when 'attachmentSet'
@in_attachment_set = true
end
end
def end_element(name)
if @in_tag_set
case name
when 'item'
@vpc['tagSet'][@tag['key']] = @tag['value']
@tag = {}
when 'key', 'value'
@tag[name] = value
when 'tagSet'
@in_tag_set = false
end
elsif @in_attachment_set
case name
when 'item'
@internet_gateway['attachmentSet']=@attachment
@attachment = {}
when 'vpcId', 'state'
@attachment[name] = value
when 'attachmentSet'
@in_attachment_set = false
end
else
case name
when 'internetGatewayId'
@internet_gateway[name] = value
when 'item'
@response['internetGatewaySet'] << @internet_gateway
@internet_gateway = { 'tagSet' => {} }
@internet_gateway = { 'attachmentSet' => {} }
when 'requestId'
@response[name] = value
end
end
end
end
end
end
end
end

View file

@ -12,7 +12,7 @@ module Fog
def end_element(name)
case name
when 'availabilityZone', 'instanceType', 'productDescription', 'reservedInstancesId', 'state'
when 'availabilityZone', 'instanceType', 'productDescription', 'reservedInstancesId', 'state', 'offeringType'
@reserved_instance[name] = value
when 'duration', 'instanceCount'
@reserved_instance[name] = value.to_i

View file

@ -3,64 +3,81 @@ module Fog
module Compute
module AWS
class DescribeVolumeStatus < Fog::Parsers::Base
def new_volume
@volume = { 'volumeStatus' => { 'details' => [] }, 'eventSet' => {}, 'actionSet' => {} }
end
def reset
@volume_status = {}
@action_set = {}
@detail = {}
@event_set = {}
@volume_status = { 'details' => [] }
@volume = { 'actionsSet' => [], 'eventsSet' => [] }
@response = { 'volumeStatusSet' => [] }
@inside = nil
end
def start_element(name, attrs=[])
super
case name
when 'item'
new_volume if @inside.nil?
when 'volumeStatus'
@inside = :volume_status
when 'actionsSet'
@in_actions_set = true
when 'details'
@inside = :details
when 'eventSet'
@inside = :event
when 'actionSet'
@inside = :action
@in_details = true
when 'eventsSet'
@in_events_set = true
when 'volumeStatus'
@in_volume_status = true
end
end
def end_element(name)
case name
#Simple closers
when 'details'
@inside = nil
when 'volumeStatus'
@inside = nil
when 'eventSet'
@inside = nil
when 'actionSet'
@inside = nil
when 'item'
@response['volumeStatusSet'] << @volume if @inside.nil?
#Top level
when 'nextToken', 'requestId'
@response[name] = value
# Volume Stuff
when 'volumeId', 'availabilityZone'
@volume[name] = value
#The mess...
when 'name', 'status'
case @inside
when :details
@volume['volumeStatus']['details'] << {name => value }
when :volume_status
@volume['volumeStatus'][name] = value
if @in_actions_set
case name
when 'actionsSet'
@in_actions_set = false
when 'code', 'eventId', 'eventType', 'description'
@action_set[name] = value.strip
when 'item'
@volume['actionsSet'] << @action_set
@action_set = {}
end
elsif @in_details
case name
when 'details'
@in_details = false
when 'name', 'status'
@detail[name] = value
when 'item'
@volume_status['details'] << @detail
@detail = {}
end
elsif @in_events_set
case name
when 'eventsSet'
@in_events_set = false
when 'code', 'eventId', 'eventType', 'description'
@event_set[name] = value.strip
when 'notAfter', 'notBefore'
@event_set[name] = Time.parse(value)
when 'item'
@volume['eventsSet'] << @event_set
@event_set = {}
end
elsif @in_volume_status
case name
when 'volumeStatus'
@volume['volumeStatus'] = @volume_status
@volume_status = { 'details' => [] }
@in_volume_status = false
when 'status'
@volume_status[name] = value
end
else
case name
when 'volumeId', 'availabilityZone'
@volume[name] = value
when 'nextToken', 'requestId'
@response[name] = value
when 'item'
@response['volumeStatusSet'] << @volume
@volume = { 'actionsSet' => [], 'eventsSet' => [] }
end
when 'code', 'eventId', 'eventType', 'description'
@volume["#{@inside}Set"][name] = value.strip
when 'notAfter', 'notBefore'
@volume["#{@inside}Set"][name] = Time.parse(value)
end
end
end

View file

@ -2,9 +2,7 @@ module Fog
module Parsers
module Compute
module AWS
class DescribeVolumes < Fog::Parsers::Base
def reset
@attachment = {}
@in_attachment_set = false

View file

@ -0,0 +1,24 @@
module Fog
module Parsers
module Compute
module AWS
class DetachInternetGateway < Fog::Parsers::Base
def end_element(name)
case name
when 'requestId'
@response[name] = value
when 'return'
if value == 'true'
@response[name] = true
else
@response[name] = false
end
end
end
end
end
end
end
end

View file

@ -0,0 +1,26 @@
module Fog
module Parsers
module AWS
module ELB
class ApplySecurityGroupsToLoadBalancer < Fog::Parsers::Base
def reset
@response = { 'ApplySecurityGroupsToLoadBalancerResult' => { 'SecurityGroups' => [] }, 'ResponseMetadata' => {} }
end
def end_element(name)
case name
when 'member'
@response['ApplySecurityGroupsToLoadBalancerResult']['SecurityGroups'] << value
when 'RequestId'
@response['ResponseMetadata'][name] = value
end
end
end
end
end
end
end

View file

@ -0,0 +1,26 @@
module Fog
module Parsers
module AWS
module ELB
class AttachLoadBalancerToSubnets < Fog::Parsers::Base
def reset
@response = { 'AttachLoadBalancerToSubnetsResult' => { 'Subnets' => [] }, 'ResponseMetadata' => {} }
end
def end_element(name)
case name
when 'member'
@response['AttachLoadBalancerToSubnetsResult']['Subnets'] << value
when 'RequestId'
@response['ResponseMetadata'][name] = value
end
end
end
end
end
end
end

View file

@ -14,7 +14,7 @@ module Fog
end
def reset_load_balancer
@load_balancer = { 'ListenerDescriptions' => [], 'Instances' => [], 'AvailabilityZones' => [], 'Policies' => {'AppCookieStickinessPolicies' => [], 'LBCookieStickinessPolicies' => [] }, 'HealthCheck' => {}, 'SourceSecurityGroup' => {} }
@load_balancer = { 'Subnets' => [], 'SecurityGroups' => [], 'ListenerDescriptions' => [], 'Instances' => [], 'AvailabilityZones' => [], 'Policies' => {'AppCookieStickinessPolicies' => [], 'LBCookieStickinessPolicies' => [] }, 'HealthCheck' => {}, 'SourceSecurityGroup' => {} }
end
def reset_listener_description
@ -34,6 +34,10 @@ module Fog
@in_instances = true
when 'AvailabilityZones'
@in_availability_zones = true
when 'SecurityGroups'
@in_security_groups = true
when 'Subnets'
@in_subnets = true
when 'PolicyNames'
@in_policy_names = true
when 'Policies'
@ -52,6 +56,10 @@ module Fog
@listener_description['PolicyNames'] << value
elsif @in_availability_zones
@load_balancer['AvailabilityZones'] << value
elsif @in_security_groups
@load_balancer['SecurityGroups'] << value
elsif @in_subnets
@load_balancer['Subnets'] << value
elsif @in_listeners
@load_balancer['ListenerDescriptions'] << @listener_description
reset_listener_description
@ -66,7 +74,7 @@ module Fog
reset_load_balancer
end
when 'CanonicalHostedZoneName', 'CanonicalHostedZoneNameID', 'LoadBalancerName', 'DNSName'
when 'CanonicalHostedZoneName', 'CanonicalHostedZoneNameID', 'LoadBalancerName', 'DNSName', 'Scheme'
@load_balancer[name] = value
when 'CreatedTime'
@load_balancer[name] = Time.parse(value)
@ -84,9 +92,15 @@ module Fog
@in_instances = false
when 'InstanceId'
@load_balancer['Instances'] << value
when 'VPCId'
@load_balancer[name] = value
when 'AvailabilityZones'
@in_availability_zones = false
when 'SecurityGroups'
@in_security_groups = false
when 'Subnets'
@in_subnets = false
when 'Policies'
@in_policies = false

View file

@ -0,0 +1,26 @@
module Fog
module Parsers
module AWS
module ELB
class DetachLoadBalancerFromSubnets < Fog::Parsers::Base
def reset
@response = { 'DetachLoadBalancerFromSubnetsResult' => { 'Subnets' => [] }, 'ResponseMetadata' => {} }
end
def end_element(name)
case name
when 'member'
@response['DetachLoadBalancerFromSubnetsResult']['Subnets'] << value
when 'RequestId'
@response['ResponseMetadata'][name] = value
end
end
end
end
end
end
end

View file

@ -7,13 +7,19 @@ module Fog
# http://docs.amazonwebservices.com/IAM/latest/APIReference/API_GetUserPolicy.html
def reset
@response = {}
@response = { 'Policy' => {} }
end
def end_element(name)
case name
when 'UserName', 'PolicyName', 'PolicyDocument'
@response[name] = value
when 'UserName', 'PolicyName'
@response['Policy'][name] = value
when 'PolicyDocument'
@response['Policy'][name] = if decoded_string = URI.decode(value)
Fog::JSON.decode(decoded_string) rescue value
else
value
end
when 'RequestId'
@response[name] = value
end

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -61,7 +61,6 @@ module Fog
def self.data
@data ||= Hash.new do |hash, region|
owner_id = Fog::AWS::Mock.owner_id
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:servers => {},

View file

@ -23,8 +23,7 @@ module Fog
# * 'Ebs.VolumeSize'<~Integer> - The volume size, in GigaBytes.
# * 'VirtualName'<~String> - The virtual name associated with the
# device.
# * 'InstanceMonitoring'<~Hash>:
# * 'Enabled'<~Boolean> - Enabled detailed monitoring.
# * 'InstanceMonitoring.Enabled'<~Boolean> - Enable/Disable detailed monitoring, default is enabled
# * 'KernelId'<~String> - The ID of the kernel associated with the
# EC2 AMI.
# * 'KeyName'<~String> - The name of the EC2 key pair.
@ -79,7 +78,7 @@ module Fog
'BlockDeviceMappings' => [],
'CreatedTime' => Time.now.utc,
'ImageId' => image_id,
'InstanceMonitoring' => { 'Enabled' => true },
'InstanceMonitoring.Enabled' => true,
'InstanceType' => instance_type,
'KernelId' => nil,
'KeyName' => nil,

View file

@ -0,0 +1,47 @@
module Fog
module AWS
class AutoScaling
class Real
require 'fog/aws/parsers/auto_scaling/basic'
# Deletes notifications created by put_notification_configuration.
#
# ==== Parameters
# * auto_scaling_group_name<~String> - The name of the Auto Scaling
# group.
# * topic_arn<~String> - The Amazon Resource Name (ARN) of the Amazon Simple Notification Service (SNS) topic
# you wish to delete.
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'ResponseMetadata'<~Hash>:
# * 'RequestId'<~String> - Id of request
#
# ==== See Also
# http://docs.amazonwebservices.com/AutoScaling/latest/APIReference/API_DeleteNotificationConfiguration.html
#
def delete_notification_configuration(auto_scaling_group_name, topic_arn)
request({
'Action' => 'DeleteNotificationConfiguration',
'AutoScalingGroupName' => auto_scaling_group_name,
'TopicARN' => topic_arn,
:parser => Fog::Parsers::AWS::AutoScaling::Basic.new
})
end
end
class Mock
def delete_notification_configuration(auto_scaling_group_name, topic_arn)
Fog::Mock.not_implemented
end
end
end
end
end

View file

@ -0,0 +1,57 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/associate_dhcp_options'
#
#
# ==== Parameters
# * dhcp_options_id<~String> - The ID of the DHCP options you want to associate with the VPC, or "default" if you want the VPC
# to use no DHCP options.
# * vpc_id<~String> - The ID of the VPC
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'return'<~Boolean> - Returns true if the request succeeds.
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AssociateDhcpOptions.html]
def associate_dhcp_options(dhcp_options_id, vpc_id)
request(
'Action' => 'AssociateDhcpOptions',
'DhcpOptionsId' => dhcp_options_id,
'VpcId' => vpc_id,
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::AttachInternetGateway.new
)
end
end
class Mock
def associate_dhcp_options(dhcp_options_id, vpc_id)
response = Excon::Response.new
if dhcp_options_id && vpc_id
response.status = 200
response.body = {
'requestId' => Fog::AWS::Mock.request_id,
'return' => true
}
response
else
if !dhcp_options_id
message << 'The request must contain the parameter dhcp_options_id'
elsif !vpc_id
message << 'The request must contain the parameter vpc_id'
end
raise Fog::Compute::AWS::Error.new(message)
end
end
end
end
end
end

View file

@ -0,0 +1,56 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/attach_internet_gateway'
# Attaches an Internet gateway to a VPC, enabling connectivity between the Internet and the VPC
#
# ==== Parameters
# * internet_gateway_id<~String> - The ID of the Internet gateway to attach
# * vpc_id<~String> - The ID of the VPC
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'return'<~Boolean> - Returns true if the request succeeds.
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AttachInternetGateway.html]
def attach_internet_gateway(internet_gateway_id, vpc_id)
request(
'Action' => 'AttachInternetGateway',
'InternetGatewayId' => internet_gateway_id,
'VpcId' => vpc_id,
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::AttachInternetGateway.new
)
end
end
class Mock
def attach_internet_gateway(internet_gateway_id, vpc_id)
response = Excon::Response.new
if internet_gateway_id && vpc_id
response.status = 200
response.body = {
'requestId' => Fog::AWS::Mock.request_id,
'return' => true
}
response
else
if !internet_gateway_id
message << 'The request must contain the parameter internet_gateway_id'
elsif !vpc_id
message << 'The request must contain the parameter vpc_id'
end
raise Fog::Compute::AWS::Error.new(message)
end
end
end
end
end
end

View file

@ -184,7 +184,7 @@ module Fog
'ipProtocol' => permission['IpProtocol'],
'fromPort' => Integer(permission['FromPort']),
'toPort' => Integer(permission['ToPort']),
'groups' => (permission['Groups'] || []).map {|g| {'groupName' => g['GroupName'], 'userId' => g['UserId'] || self.data[:owner_id], 'groupId' => self.data[:security_groups][g['GroupName']]['groupId']} },
'groups' => (permission['Groups'] || []).map {|g| {'groupName' => g['GroupName'], 'userId' => g['UserId'] || self.data[:owner_id], 'groupId' => self.data[:security_groups][g['GroupName']] && self.data[:security_groups][g['GroupName']]['groupId']} },
'ipRanges' => (permission['IpRanges'] || []).map {|r| { 'cidrIp' => r['CidrIp'] } }
}
else

View file

@ -0,0 +1,75 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/create_dhcp_options'
# Creates a set of DHCP options for your VPC
#
# ==== Parameters
# * DhcpConfigurationOptions<~Hash> - hash of key value dhcp options to assign
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateDhcpOptions.html]
def create_dhcp_options(dhcp_configurations = {})
params = {}
params.merge!(indexed_multidimensional_params(dhcp_configurations))
request({
'Action' => 'CreateDhcpOptions',
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::CreateDhcpOptions.new
}.merge!(params))
end
private
def indexed_multidimensional_params(multi_params)
params = {}
multi_params.keys.each_with_index do |key, key_index|
key_index += 1
params[format('DhcpConfiguration.%d.Key', key_index)] = key
[*multi_params[key]].each_with_index do |value, value_index|
value_index += 1
params[format('DhcpConfiguration.%d.Value.%d', key_index, value_index)] = value
end
end
params
end
end
class Mock
def create_dhcp_options(dhcp_configurations = {})
params = {}
params.merge!(indexed_multidimensional_params(dhcp_configurations))
Excon::Response.new.tap do |response|
response.status = 200
response.body = {
'requestId' => Fog::AWS::Mock.request_id,
'dhcpOptionsSet' => [
'dhcpOptionsId' => Fog::AWS::Mock.dhcp_options_id,
'dhcpConfigurationSet' => {},
'tagSet' => {}
]
}
end
end
private
def indexed_multidimensional_params(multi_params)
params = {}
multi_params.keys.each_with_index do |key, key_index|
key_index += 1
params[format('DhcpConfiguration.%d.Key', key_index)] = key
[*multi_params[key]].each_with_index do |value, value_index|
value_index += 1
params[format('DhcpConfiguration.%d.Value.%d', key_index, value_index)] = value
end
end
params
end
end
end
end
end

View file

@ -0,0 +1,51 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/create_internet_gateway'
# Creates an InternetGateway
#
# ==== Parameters
# (none)
#
# === Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'internetGateway'<~Array>:
# * 'attachmentSet'<~Array>: A list of VPCs attached to the Internet gateway
# * 'vpcId'<~String> - The ID of the VPC the Internet gateway is attached to.
# * 'state'<~String> - The current state of the attachment.
# * 'tagSet'<~Array>: Tags assigned to the resource.
# * 'key'<~String> - Tag's key
# * 'value'<~String> - Tag's value
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-InternetGatewayAttachmentType.html]
def create_internet_gateway()
request({
'Action' => 'CreateInternetGateway',
:parser => Fog::Parsers::Compute::AWS::CreateInternetGateway.new
})
end
end
class Mock
def create_internet_gateway()
Excon::Response.new(
:status => 200,
:body => {
'requestId' => Fog::AWS::Mock.request_id,
'internetGatewaySet' => [
'internetGatewayId' => Fog::AWS::Mock.request_id,
'attachmentSet' => {},
'tagSet' => {}
]
}
)
end
end
end
end
end

View file

@ -0,0 +1,50 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/delete_dhcp_options'
#Deletes a set of DHCP options that you specify. Amazon VPC returns an error if the set of options you specify is currently
#associated with a VPC. You can disassociate the set of options by associating either a new set of options or the default
#options with the VPC.
#
# ==== Parameters
# * dhcp_options_id<~String> - The ID of the DHCP options set you want to delete.
#
# === Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'return'<~Boolean> - Returns true if the request succeeds.
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteDhcpOptions.html]
def delete_dhcp_options(dhcp_options_id)
request(
'Action' => 'DeleteDhcpOptions',
'DhcpOptionsId' => dhcp_options_id,
:parser => Fog::Parsers::Compute::AWS::DeleteDhcpOptions.new
)
end
end
class Mock
def delete_dhcp_options(dhcp_options_id)
Excon::Response.new.tap do |response|
if dhcp_options_id
response.status = 200
response.body = {
'requestId' => Fog::AWS::Mock.request_id,
'return' => true
}
else
message = 'MissingParameter => '
message << 'The request must contain the parameter dhcp_options_id'
raise Fog::Compute::AWS::Error.new(message)
end
end
end
end
end
end
end

View file

@ -0,0 +1,48 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/delete_internet_gateway'
#Deletes an Internet gateway from your AWS account. The gateway must not be attached to a VPC
#
# ==== Parameters
# * internet_gateway_id<~String> - The ID of the InternetGateway you want to delete.
#
# === Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'return'<~Boolean> - Returns true if the request succeeds.
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteInternetGateway.html]
def delete_internet_gateway(internet_gateway_id)
request(
'Action' => 'DeleteInternetGateway',
'InternetGatewayId' => internet_gateway_id,
:parser => Fog::Parsers::Compute::AWS::DeleteInternetGateway.new
)
end
end
class Mock
def delete_internet_gateway(internet_gateway_id)
Excon::Response.new.tap do |response|
if internet_gateway_id
response.status = 200
response.body = {
'requestId' => Fog::AWS::Mock.request_id,
'return' => true
}
else
message = 'MissingParameter => '
message << 'The request must contain the parameter internet_gateway_id'
raise Fog::Compute::AWS::Error.new(message)
end
end
end
end
end
end
end

View file

@ -0,0 +1,62 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/describe_dhcp_options'
# Describe all or specified dhcp_options
#
# ==== Parameters
# * filters<~Hash> - List of filters to limit results with
#
# === Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'DhcpOptionsSet'<~Array>:
# * 'dhcpOptionsId'<~String> - The ID of the Dhcp Options
# * 'dhcpConfigurationSet'<~Array>: - The list of options in the set.
# * 'key'<~String> - The name of a DHCP option.
# * 'valueSet'<~Array>: A set of values for a DHCP option.
# * 'value'<~String> - The value of a DHCP option.
# * 'tagSet'<~Array>: Tags assigned to the resource.
# * 'key'<~String> - Tag's key
# * 'value'<~String> - Tag's value
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-DhcpOptionsType.html]
def describe_dhcp_options(filters = {})
unless filters.is_a?(Hash)
Fog::Logger.warning("describe_dhcp_options with #{filters.class} param is deprecated, use dhcp_options('dhcp-options-id' => []) instead [light_black](#{caller.first})[/]")
filters = {'dhcp-options-id' => [*filters]}
end
params = Fog::AWS.indexed_filters(filters)
request({
'Action' => 'DescribeDhcpOptions',
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::DescribeDhcpOptions.new
}.merge!(params))
end
end
class Mock
def describe_dhcp_options(filters = {})
Excon::Response.new.tap do |response|
response.status = 200
response.body = {
'requestId' => Fog::AWS::Mock.request_id,
'dhcpOptionsSet' => [
'dhcpOptionsId' => Fog::AWS::Mock.dhcp_options_id,
'dhcpConfigurationSet' => {
'key' => 'domain-name',
'valueSet' => ["example.com"],
},
'tagSet' => {}
]
}
end
end
end
end
end
end

View file

@ -183,6 +183,9 @@ module Fog
end
when 'rebooting'
instance['instanceState'] = { 'code' => 16, 'name' => 'running' }
when 'stopping'
instance['instanceState'] = { 'code' => 0, 'name' => 'stopping' }
instance['stateReason'] = { 'code' => 0 }
when 'shutting-down'
if Time.now - self.data[:deleted_at][instance['instanceId']] >= Fog::Mock.delay * 2
self.data[:deleted_at].delete(instance['instanceId'])

View file

@ -0,0 +1,61 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/describe_internet_gateways'
# Describe all or specified internet_gateways
#
# ==== Parameters
# * filters<~Hash> - List of filters to limit results with
#
# === Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'InternetGatewaySet'<~Array>:
# * 'internetGatewayId'<~String> - The ID of the Internet gateway.
# * 'attachmentSet'<~Array>: - A list of VPCs attached to the Internet gateway
# * 'vpcId'<~String> - The ID of the VPC the Internet gateway is attached to
# * 'state'<~String> - The current state of the attachment
# * 'tagSet'<~Array>: Tags assigned to the resource.
# * 'key'<~String> - Tag's key
# * 'value'<~String> - Tag's value
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-InternetGatewayType.html]
def describe_internet_gateways(filters = {})
unless filters.is_a?(Hash)
Fog::Logger.warning("describe_internet_gateways with #{filters.class} param is deprecated, use internet_gateways('internet-gateway-id' => []) instead [light_black](#{caller.first})[/]")
filters = {'internet-gateway-id' => [*filters]}
end
params = Fog::AWS.indexed_filters(filters)
request({
'Action' => 'DescribeInternetGateways',
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::DescribeInternetGateways.new
}.merge!(params))
end
end
class Mock
def describe_internet_gateways(filters = {})
Excon::Response.new.tap do |response|
response.status = 200
response.body = {
'requestId' => Fog::AWS::Mock.request_id,
'internetGatewaySet' => [
'internetGatewayId' => Fog::AWS::Mock.request_id,
'attachmentSet' => {
'vpcId' => Fog::AWS::Mock.request_id,
'state' => 'pending',
},
'tagSet' => {}
]
}
end
end
end
end
end
end

View file

@ -0,0 +1,56 @@
module Fog
module Compute
class AWS
class Real
require 'fog/aws/parsers/compute/detach_internet_gateway'
# Detaches an Internet gateway to a VPC, enabling connectivity between the Internet and the VPC
#
# ==== Parameters
# * internet_gateway_id<~String> - The ID of the Internet gateway to detach
# * vpc_id<~String> - The ID of the VPC
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'return'<~Boolean> - Returns true if the request succeeds.
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DetachInternetGateway.html]
def detach_internet_gateway(internet_gateway_id, vpc_id)
request(
'Action' => 'DetachInternetGateway',
'InternetGatewayId' => internet_gateway_id,
'VpcId' => vpc_id,
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::DetachInternetGateway.new
)
end
end
class Mock
def detach_internet_gateway(internet_gateway_id, vpc_id)
response = Excon::Response.new
if internet_gateway_id && vpc_id
response.status = 200
response.body = {
'requestId' => Fog::AWS::Mock.request_id,
'return' => true
}
response
else
if !internet_gateway_id
message << 'The request must contain the parameter internet_gateway_id'
elsif !vpc_id
message << 'The request must contain the parameter vpc_id'
end
raise Fog::Compute::AWS::Error.new(message)
end
end
end
end
end
end

View file

@ -73,10 +73,10 @@ module Fog
'imageOwnerId' => self.data[:owner_id],
'isPublic' => false,
'productCodes' => [],
'architecture' => 'i386',
'architecture' => options['Architecture'] || 'i386',
'imageType' => 'machine',
'kernelId' => Fog::AWS::Mock.kernel_id,
'ramdiskId' => Fog::AWS::Mock.ramdisk_id,
'kernelId' => options['KernelId'] || Fog::AWS::Mock.kernel_id,
'ramdiskId' => options['RamdiskId'] || Fog::AWS::Mock.ramdisk_id,
'platform' => 'Linux',
'stateReason' => {},
'imageOwnerAlias' => self.data[:owner_id],

View file

@ -27,6 +27,33 @@ module Fog
end
end
class Mock
def start_instances(instance_id)
instance_ids = Array(instance_id)
instance_set = self.data[:instances].values
instance_set = apply_tag_filters(instance_set, {'instance_id' => instance_ids}, 'instanceId')
if instance_set.empty?
raise Fog::Compute::AWS::NotFound.new("The instance ID '#{instance_ids.first}' does not exist")
else
response = Excon::Response.new
response.status = 200
response.body = {
'instancesSet' => instance_set.inject([]) do |ia, instance|
ia << {'currentState' => { 'code' => 0, 'name' => 'pending' },
'previousState' => instance['instanceState'],
'instanceId' => instance['instanceId'] }
instance['instanceState'] = {'code'=>0, 'name'=>'pending'}
ia
end
}
response
end
end
end
end
end
end

View file

@ -28,6 +28,33 @@ module Fog
end
end
class Mock
def stop_instances(instance_id, force = false)
instance_ids = Array(instance_id)
instance_set = self.data[:instances].values
instance_set = apply_tag_filters(instance_set, {'instance_id' => instance_ids}, 'instanceId')
if instance_set.empty?
raise Fog::Compute::AWS::NotFound.new("The instance ID '#{instance_ids.first}' does not exist")
else
response = Excon::Response.new
response.status = 200
response.body = {
'instancesSet' => instance_set.inject([]) do |ia, instance|
ia << {'currentState' => { 'code' => 0, 'name' => 'stopping' },
'previousState' => instance['instanceState'],
'instanceId' => instance['instanceId'] }
instance['instanceState'] = {'code'=>0, 'name'=>'stopping'}
ia
end
}
response
end
end
end
end
end
end

View file

@ -29,7 +29,7 @@ module Fog
# * 'Id'<~String> - The ID of the request
# * 'Status'<~String> - status of the request - PENDING | INSYNC
# * 'SubmittedAt'<~String> - The date and time the change was made
# * status<~Integer> - 201 when successful
# * status<~Integer> - 200 when successful
#
# ==== Examples
#
@ -131,6 +131,61 @@ module Fog
end
end
class Mock
def change_resource_record_sets(zone_id, change_batch, options = {})
response = Excon::Response.new
errors = []
if (zone = self.data[:zones][zone_id])
response.status = 200
change_batch.each do |change|
case change[:action]
when "CREATE"
if zone[:records][change[:type]].nil?
zone[:records][change[:type]] = {}
end
if zone[:records][change[:type]][change[:name]].nil?
zone[:records][change[:type]][change[:name]] = {
:name => change[:name],
:type => change[:type],
:ttl => change[:ttl],
:resource_records => change[:resource_records]
}
else
errors << "Tried to create resource record set #{change[:name]}. type #{change[:type]}, but it already exists"
end
when "DELETE"
if zone[:records][change[:type]].nil? || zone[:records][change[:type]].delete(change[:name]).nil?
errors << "Tried to delete resource record set #{change[:name]}. type #{change[:type]}, but it was not found"
end
end
end
if errors.empty?
response.body = {
'ChangeInfo' => {
'Id' => "/change/#{Fog::AWS::Mock.change_id}",
'Status' => 'INSYNC',
'SubmittedAt' => Time.now.utc.iso8601
}
}
response
else
response.status = 400
response.body = "<?xml version=\"1.0\"?><InvalidChangeBatch xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><Messages>#{errors.map {|e| "<Message>#{e}</Message>"}.join()}</Messages></InvalidChangeBatch>"
raise(Excon::Errors.status_error({:expects => 200}, response))
end
else
response.status = 404
response.body = "<?xml version=\"1.0\"?><Response><Errors><Error><Code>NoSuchHostedZone</Code><Message>A hosted zone with the specified hosted zone ID does not exist.</Message></Error></Errors><RequestID>#{Fog::AWS::Mock.request_id}</RequestID></Response>"
raise(Excon::Errors.status_error({:expects => 200}, response))
end
end
end
end
end
end

View file

@ -54,6 +54,51 @@ module Fog
end
end
class Mock
require 'time'
def create_hosted_zone(name, options = {})
response = Excon::Response.new
if list_hosted_zones.body['HostedZones'].find_all {|z| z['Name'] == name}.size < self.data[:limits][:duplicate_domains]
response.status = 201
if options[:caller_ref]
caller_ref = options[:caller_ref]
else
#make sure we have a unique call reference
caller_ref = "ref-#{rand(1000000).to_s}"
end
zone_id = "/hostedzone/#{Fog::AWS::Mock.zone_id}"
self.data[:zones][zone_id] = {
:id => zone_id,
:name => name,
:reference => caller_ref,
:comment => options[:comment],
:records => {}
}
response.body = {
'HostedZone' => {
'Id' => zone_id,
'Name' => name,
'CallerReference' => caller_ref,
'Comment' => options[:comment]
},
'ChangeInfo' => {
'Id' => "/change/#{Fog::AWS::Mock.change_id}",
'Status' => 'INSYNC',
'SubmittedAt' => Time.now.utc.iso8601
},
'NameServers' => Fog::AWS::Mock.nameservers
}
response
else
response.status = 400
response.body = "<?xml version=\"1.0\"?><Response><Errors><Error><Code>DelegationSetNotAvailable</Code><Message>Amazon Route 53 allows some duplication, but Amazon Route 53 has a maximum threshold of duplicated domains. This error is generated when you reach that threshold. In this case, the error indicates that too many hosted zones with the given domain name exist. If you want to create a hosted zone and Amazon Route 53 generates this error, contact Customer Support.</Message></Error></Errors><RequestID>#{Fog::AWS::Mock.request_id}</RequestID></Response>"
raise(Excon::Errors.status_error({:expects => 200}, response))
end
end
end
end
end
end

View file

@ -20,7 +20,7 @@ module Fog
# * 'Comment'<~String> -
# * 'NameServers'<~Array>
# * 'NameServer'<~String>
# * status<~Integer> - 201 when successful
# * status<~Integer> - 200 when successful
def get_hosted_zone(zone_id)
# AWS methods return zone_ids that looks like '/hostedzone/id'. Let the caller either use
@ -37,6 +37,29 @@ module Fog
end
end
class Mock
def get_hosted_zone(zone_id)
response = Excon::Response.new
if (zone = self.data[:zones][zone_id])
response.status = 200
response.body = {
'HostedZone' => {
'Id' => zone[:id],
'Name' => zone[:name],
'CallerReference' => zone[:reference],
'Comment' => zone[:comment]
},
'NameServers' => Fog::AWS::Mock.nameservers
}
response
else
response.status = 404
response.body = "<?xml version=\"1.0\"?><Response><Errors><Error><Code>NoSuchHostedZone</Code><Message>A hosted zone with the specified hosted zone ID does not exist.</Message></Error></Errors><RequestID>#{Fog::AWS::Mock.request_id}</RequestID></Response>"
raise(Excon::Errors.status_error({:expects => 200}, response))
end
end
end
end
end
end

View file

@ -49,6 +49,51 @@ module Fog
end
end
class Mock
def list_hosted_zones(options = {})
if options[:max_items].nil?
maxitems = 100
else
maxitems = options[:max_items]
end
if options[:marker].nil?
start = 0
else
start = self.data[:zones].find_index {|z| z[:id] == options[:marker]}
end
zones = self.data[:zones].values[start, maxitems]
next_zone = self.data[:zones].values[start + maxitems]
truncated = !next_zone.nil?
response = Excon::Response.new
response.status = 200
response.body = {
'HostedZones' => zones.map do |z|
{
'Id' => z[:id],
'Name' => z[:name],
'CallerReference' => z[:reference],
'Comment' => z[:comment],
}
end,
'Marker' => options[:marker].to_s,
'MaxItems' => options[:max_items].to_s,
'IsTruncated' => truncated.to_s
}
if truncated
response.body['NextMarker'] = next_zone[:id]
end
response
end
end
end
end
end

View file

@ -3,6 +3,11 @@ module Fog
class DynamoDB
class Real
def batch_put_item(request_items)
Fog::Logger.deprecation("batch_put_item is deprecated, use batch_write_item instead")
batch_write_item(request_items)
end
#request_items has form:
#{"table_name"=>
# [{"PutRequest"=>
@ -13,7 +18,7 @@ module Fog
# }}}, ... ]}
# For more information:
# http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_BatchWriteItems.html
def batch_put_item(request_items)
def batch_write_item(request_items)
body = {
'RequestItems' => request_items
}

View file

@ -0,0 +1,61 @@
module Fog
module AWS
class ELB
class Real
require 'fog/aws/parsers/elb/apply_security_groups_to_load_balancer'
# Sets the security groups for an ELB in VPC
#
# ==== Parameters
# * security_group_ids<~Array> - List of security group ids to enable on ELB
# * lb_name<~String> - Load balancer to disable availability zones on
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'ResponseMetadata'<~Hash>:
# * 'RequestId'<~String> - Id of request
# * 'ApplySecurityGroupsToLoadBalancer'<~Hash>:
# * 'SecurityGroups'<~Array> - array of strings describing the security group ids currently enabled
def apply_security_groups_to_load_balancer(security_group_ids, lb_name)
params = Fog::AWS.indexed_param('SecurityGroups.member', [*security_group_ids])
request({
'Action' => 'ApplySecurityGroupsToLoadBalancer',
'LoadBalancerName' => lb_name,
:parser => Fog::Parsers::AWS::ELB::ApplySecurityGroupsToLoadBalancer.new
}.merge!(params))
end
alias :apply_security_groups :apply_security_groups_to_load_balancer
end
class Mock
def apply_security_groups_to_load_balancer(security_group_ids, lb_name)
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['SecurityGroups'] << security_group_ids
load_balancer['SecurityGroups'].flatten!.uniq!
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'DetachLoadBalancerFromSubnetsResult' => {
'SecurityGroups' => load_balancer['SecurityGroups']
}
}
response
end
alias :apply_security_groups :apply_security_groups_to_load_balancer
end
end
end
end

View file

@ -0,0 +1,61 @@
module Fog
module AWS
class ELB
class Real
require 'fog/aws/parsers/elb/attach_load_balancer_to_subnets'
# Enable a subnet for an existing ELB
#
# ==== Parameters
# * subnet_ids<~Array> - List of subnet ids to enable on ELB
# * lb_name<~String> - Load balancer to enable availability zones on
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'ResponseMetadata'<~Hash>:
# * 'RequestId'<~String> - Id of request
# * 'AttachLoadBalancerToSubnetsResult'<~Hash>:
# * 'Subnets'<~Array> - array of strings describing the subnet ids currently enabled
def attach_load_balancer_to_subnets(subnet_ids, lb_name)
params = Fog::AWS.indexed_param('Subnets.member', [*subnet_ids])
request({
'Action' => 'AttachLoadBalancerToSubnets',
'LoadBalancerName' => lb_name,
:parser => Fog::Parsers::AWS::ELB::AttachLoadBalancerToSubnets.new
}.merge!(params))
end
alias :enable_subnets :attach_load_balancer_to_subnets
end
class Mock
def attach_load_balancer_to_subnets(subnet_ids, lb_name)
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['Subnets'] << subnet_ids
load_balancer['Subnets'].flatten!.uniq!
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'AttachLoadBalancerToSubnetsResult' => {
'Subnets' => load_balancer['Subnets']
}
}
response
end
alias :enable_subnets :attach_load_balancer_to_subnets
end
end
end
end

View file

@ -23,8 +23,11 @@ module Fog
# * 'RequestId'<~String> - Id of request
# * 'CreateLoadBalancerResult'<~Hash>:
# * 'DNSName'<~String> - DNS name for the newly created ELB
def create_load_balancer(availability_zones, lb_name, listeners)
def create_load_balancer(availability_zones, lb_name, listeners, options = {})
params = Fog::AWS.indexed_param('AvailabilityZones.member', [*availability_zones])
params.merge!(Fog::AWS.indexed_param('Subnets.member.%d', options[:subnet_ids]))
params.merge!(Fog::AWS.serialize_keys('Scheme', options[:scheme]))
params.merge!(Fog::AWS.indexed_param('SecurityGroups.member.%d', options[:security_groups]))
listener_protocol = []
listener_lb_port = []
@ -54,7 +57,7 @@ module Fog
end
class Mock
def create_load_balancer(availability_zones, lb_name, listeners = [])
def create_load_balancer(availability_zones, lb_name, listeners = [], options = {})
response = Excon::Response.new
response.status = 200
@ -72,6 +75,9 @@ module Fog
dns_name = Fog::AWS::ELB::Mock.dns_name(lb_name, @region)
self.data[:load_balancers][lb_name] = {
'AvailabilityZones' => availability_zones,
'Subnets' => options[:subnet_ids],
'Scheme' => options[:scheme],
'SecurityGroups' => options[:security_groups],
'CanonicalHostedZoneName' => '',
'CanonicalHostedZoneNameID' => '',
'CreatedTime' => Time.now,
@ -96,7 +102,6 @@ module Fog
'OwnerAlias' => ''
}
}
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id

View file

@ -0,0 +1,61 @@
module Fog
module AWS
class ELB
class Real
require 'fog/aws/parsers/elb/detach_load_balancer_from_subnets'
# Disable a subnet for an existing ELB
#
# ==== Parameters
# * subnet_ids<~Array> - List of subnet ids to enable on ELB
# * lb_name<~String> - Load balancer to disable availability zones on
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'ResponseMetadata'<~Hash>:
# * 'RequestId'<~String> - Id of request
# * 'DetachLoadBalancerFromSubnetsResult'<~Hash>:
# * 'Subnets'<~Array> - array of strings describing the subnet ids currently enabled
def detach_load_balancer_from_subnets(subnet_ids, lb_name)
params = Fog::AWS.indexed_param('Subnets.member', [*subnet_ids])
request({
'Action' => 'DetachLoadBalancerFromSubnets',
'LoadBalancerName' => lb_name,
:parser => Fog::Parsers::AWS::ELB::DetachLoadBalancerFromSubnets.new
}.merge!(params))
end
alias :disable_subnets :detach_load_balancer_from_subnets
end
class Mock
def detach_load_balancer_from_subnets(subnet_ids, lb_name)
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['Subnets'] << subnet_ids
load_balancer['Subnets'].flatten!.uniq!
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'DetachLoadBalancerFromSubnetsResult' => {
'Subnets' => load_balancer['Subnets']
}
}
response
end
alias :disable_subnets :detach_load_balancer_from_subnets
end
end
end
end

View file

@ -39,6 +39,24 @@ module Fog
end
end
class Mock
def get_group(group_name, options = {})
raise Fog::AWS::IAM::NotFound.new(
"The user with name #{group_name} cannot be found."
) unless self.data[:groups].key?(group_name)
Excon::Response.new.tap do |response|
response.body = { 'Group' => {
'GroupId' => data[:groups][group_name][:group_id],
'Path' => data[:groups][group_name][:path],
'GroupName' => group_name,
'Arn' => (data[:groups][group_name][:arn]).strip
},
'Users' => data[:groups][group_name][:members].map { |user| get_user(user).body['User'] },
'RequestId' => Fog::AWS::Mock.request_id }
response.status = 200
end
end
end
end
end
end

View file

@ -8,6 +8,7 @@ module Fog
# Get User
#
# ==== Parameters
# * username<String>
# * options<~Hash>:
# * 'UserName'<~String>: Name of the User. Defaults to current user
#
@ -23,14 +24,33 @@ module Fog
# ==== See Also
# http://docs.amazonwebservices.com/IAM/latest/APIReference/API_Getuser.html
#
def get_user(options = {})
def get_user(username, options = {})
request({
'Action' => 'GetUser',
:parser => Fog::Parsers::AWS::IAM::GetUser.new
'Action' => 'GetUser',
'UserName' => username,
:parser => Fog::Parsers::AWS::IAM::GetUser.new
}.merge!(options))
end
end
class Mock
def get_user(user, options = {})
raise Fog::AWS::IAM::NotFound.new(
"The user with name #{user} cannot be found."
) unless self.data[:users].key?(user)
Excon::Response.new.tap do |response|
response.body = {'User' => {
'UserId' => data[:users][user][:user_id],
'Path' => data[:users][user][:path],
'UserName' => user,
'Arn' => (data[:users][user][:arn]).strip
},
'RequestId' => Fog::AWS::Mock.request_id }
response.status = 200
end
end
end
end
end
end

View file

@ -31,6 +31,23 @@ module Fog
end
end
class Mock
def get_user_policy(policy_name, user_name)
raise Fog::AWS::IAM::NotFound.new("The user with name #{user} cannot be found.") unless self.data[:users].key?(user_name)
raise Fog::AWS::IAM::NotFound.new("The policy with name #{policy_name} cannot be found.") unless self.data[:users][user_name][:policies].key?(policy_name)
Excon::Response.new.tap do |response|
response.body = { 'Policy' => {
'PolicyName' => policy_name,
'UserName' => user_name,
'PolicyDocument' => data[:users][user_name][:policies][policy_name]
},
'IsTruncated' => false,
'RequestId' => Fog::AWS::Mock.request_id
}
response.status = 200
end
end
end
end
end
end

View file

@ -11,7 +11,7 @@ module Fog
unless object_name
raise ArgumentError.new('object_name is required')
end
host, path = if bucket_name =~ /^(?:[a-z]|\d(?!\d{0,2}(?:\.\d{1,3}){3}$))(?:[a-z0-9]|\.(?![\.\-])|\-(?![\.])){1,61}[a-z0-9]$/
host, path = if bucket_name =~ /^(?:[a-z]|\d(?!\d{0,2}(?:\.\d{1,3}){3}$))(?:[a-z0-9]|\-(?![\.])){1,61}[a-z0-9]$/
["#{bucket_name}.#{@host}", object_name]
else
[@host, "#{bucket_name}/#{object_name}"]

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS
@ -21,7 +21,6 @@ module Fog
class Mock
def self.data
@data ||= Hash.new do |hash, region|
owner_id = Fog::AWS::Mock.owner_id
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:owner_id => Fog::AWS::Mock.owner_id,

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
require 'fog/storage'
module Fog
@ -331,7 +331,7 @@ DATA
partNumber
policy
requestPayment
reponse-cache-control
response-cache-control
response-content-disposition
response-content-encoding
response-content-language
@ -352,7 +352,7 @@ DATA
string_to_sign << canonical_resource
signed_string = @hmac.sign(string_to_sign)
signature = Base64.encode64(signed_string).chomp!
Base64.encode64(signed_string).chomp!
end
private

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
require 'fog/aws'
module Fog
module AWS

View file

@ -1,4 +1,4 @@
require(File.expand_path(File.join(File.dirname(__FILE__), 'core')))
require 'fog/core'
module Fog
module BareMetalCloud

View file

@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'bare_metal_cloud'))
require 'fog/bare_metal_cloud'
require 'fog/compute'
module Fog

Some files were not shown because too many files have changed in this diff Show more