Permalink
Browse files

Fog::Bouncer. ✌️

  • Loading branch information...
0 parents commit 1d6e65631230b5bfb07ca8141041800cd9ea4ca3 @dylanegan committed Feb 24, 2012
Showing with 250 additions and 0 deletions.
  1. +17 −0 .gitignore
  2. +4 −0 Gemfile
  3. +29 −0 README.md
  4. +11 −0 Rakefile
  5. BIN bouncer.jpg
  6. +22 −0 fog-bouncer.gemspec
  7. +112 −0 lib/fog/bouncer.rb
  8. +5 −0 lib/fog/bouncer/version.rb
  9. +38 −0 spec/fog/bouncer_spec.rb
  10. +12 −0 spec/helper.rb
@@ -0,0 +1,17 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
@@ -0,0 +1,4 @@
+source 'http://rubygems.org'
+
+# Specify your gem's dependencies in fog-bouncer.gemspec
+gemspec
@@ -0,0 +1,29 @@
+# fog-bouncer
+
+![fog-bouncer](https://github.com/dylanegan/fog-bouncer/raw/master/bouncer.jpg)
+
+A simple way to define and manage security groups for AWS through fog.
+
+## Usage
+
+```
+Fog::Bouncer.security do
+ account "user", "1234567890"
+
+ group "base", "Base Security Group" do
+ source "0.0.0.0/0" do
+ icmp 8..0
+ end
+
+ source "10.0.0.0/8" do
+ tcp 80, 22, 8080..8081
+ end
+ end
+
+ group "other", "Other Security Group" do
+ source "default@user" do
+ tcp 22
+ end
+ end
+end
+```
@@ -0,0 +1,11 @@
+#!/usr/bin/env rake
+require "bundler/gem_tasks"
+
+require 'rake/testtask'
+
+Rake::TestTask.new do |t|
+ t.libs.push "lib"
+ t.libs.push "spec"
+ t.test_files = FileList['spec/**/*_spec.rb']
+ t.verbose = true
+end
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,22 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/fog/bouncer/version', __FILE__)
+
+Gem::Specification.new do |gem|
+ gem.authors = ["Dylan Egan"]
+ gem.email = ["dylanegan@gmail.com"]
+ gem.description = %q{TODO: Write a gem description}
+ gem.summary = %q{TODO: Write a gem summary}
+ gem.homepage = ""
+
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ gem.files = `git ls-files`.split("\n")
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ gem.name = "fog-bouncer"
+ gem.require_paths = ["lib"]
+ gem.version = Fog::Bouncer::VERSION
+
+ gem.add_dependency "fog"
+ gem.add_dependency "rake"
+
+ gem.add_development_dependency "minitest"
+end
@@ -0,0 +1,112 @@
+require "fog"
+require "fog/bouncer/version"
+
+module Fog
+ module Bouncer
+ def self.fog
+ @fog ||= Fog::Compute.new(
+ :provider => "AWS",
+ :region => (ENV['PROVIDER_REGION'] || 'us-east-1'),
+ :aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
+ :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
+ )
+ end
+
+ def self.security(&block)
+ Fog::Bouncer::Security.new(&block)
+ end
+
+ class Security
+ def initialize(&block)
+ instance_eval(&block)
+ end
+
+ def groups
+ @groups ||= []
+ end
+
+ def group(name, description, &block)
+ groups << Group.new(name, description, &block)
+ end
+ end
+
+ class Group
+ attr_reader :name, :description
+
+ def initialize(name, description, &block)
+ @name = name
+ @description = description
+ instance_eval(&block) if block_given?
+ end
+
+ def sources
+ @sources ||= []
+ end
+
+ def source(source, &block)
+ sources << Sources.for(source, &block)
+ end
+ end
+
+ class Sources
+ def self.for(source, &block)
+ if source =~ /^\d+\.\d+\.\d+.\d+\/\d+$/
+ CIDRSource.new(source, &block)
+ else
+ GroupSource.new(source, &block)
+ end
+ end
+ end
+
+ class Source
+ def initialize(source, &block)
+ @source = source
+ instance_eval(&block) if block_given?
+ end
+
+ def protocols
+ @protocols ||= { icmp: [], tcp: [], udp: [] }
+ end
+
+ def icmp(*ports)
+ ports.each { |port| protocols[:icmp] << ICMP.new(port) }
+ end
+
+ def tcp(*ports)
+ ports.each { |port| protocols[:tcp] << TCP.new(port) }
+ end
+
+ def udp(*ports)
+ ports.each { |port| protocols[:udp] << UDP.new(port) }
+ end
+ end
+
+ class CIDRSource < Source
+ def range
+ @source
+ end
+ end
+
+ class Protocol
+ attr_reader :from, :to
+
+ def initialize(port)
+ if port.is_a?(Range)
+ @from = port.begin
+ @to = port.end
+ else
+ @from = port
+ end
+ end
+ end
+
+ class ICMP < Protocol
+ end
+
+ class TCP < Protocol
+ end
+
+ class UDP < Protocol
+ end
+ end
+end
@@ -0,0 +1,5 @@
+module Fog
+ module Bouncer
+ VERSION = "0.0.1"
+ end
+end
@@ -0,0 +1,38 @@
+require "helper"
+
+describe Fog::Bouncer do
+ before do
+ @fog = Fog::Bouncer.fog
+ end
+
+ it "bounces" do
+ true.must_equal true
+ end
+
+ describe "#security" do
+ before do
+ @doorlist = Fog::Bouncer.security do
+ group "douchebag", "Don't let them in!" do
+ source "1.1.1.1/1" do
+ tcp 7070..8080
+ end
+ end
+ end
+ end
+
+ it "has a douchebag group" do
+ douchebag = @doorlist.groups.first
+ douchebag.name.must_equal "douchebag"
+ douchebag.description.must_equal "Don't let them in!"
+
+ source = douchebag.sources.first
+ source.must_be_kind_of Fog::Bouncer::CIDRSource
+ source.range.must_equal "1.1.1.1/1"
+
+ protocol = source.protocols[:tcp].first
+ protocol.must_be_kind_of Fog::Bouncer::TCP
+ protocol.from.must_equal 7070
+ protocol.to.must_equal 8080
+ end
+ end
+end
@@ -0,0 +1,12 @@
+require "minitest/autorun"
+
+ENV['AWS_ACCESS_KEY_ID'] ||= "abcde1234"
+ENV['AWS_SECRET_ACCESS_KEY'] ||= "abcde1234"
+
+require "fog/bouncer"
+
+Fog.mock! unless ENV['FOG_REAL']
+
+MiniTest::Unit.after_tests do
+ Fog::Mock.reset if Fog.mocking?
+end

0 comments on commit 1d6e656

Please sign in to comment.