gce-metadata 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.rakeTasks +7 -0
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/ChangeLog.md +4 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +41 -0
- data/LICENSE +20 -0
- data/README.md +61 -0
- data/Rakefile +21 -0
- data/gce_metadata.gemspec +39 -0
- data/lib/gce_metadata/base.rb +140 -0
- data/lib/gce_metadata/command.rb +79 -0
- data/lib/gce_metadata/dummy.rb +41 -0
- data/lib/gce_metadata/dummy.yml +34 -0
- data/lib/gce_metadata/http_client.rb +29 -0
- data/lib/gce_metadata/revision.rb +23 -0
- data/lib/gce_metadata/root.rb +21 -0
- data/lib/gce_metadata/version.rb +4 -0
- data/lib/gce_metadata.rb +73 -0
- data/spec/gce-metadata.rb +4 -0
- data/spec/gce_metadata_spec.rb +8 -0
- data/spec/spec_helper.rb +4 -0
- metadata +159 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 27f28122ea5e757ba54cdb09284ce4239dc52ae0
|
|
4
|
+
data.tar.gz: d63f87fd7de36b51b1f7c269aa7d0a75947ba5e9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 5bbf27f6fffd59010a3d287b8187e565a15a0f538dda9426d18825929f817f4c703d54acedd66d21ac901bae9716762b4fc0e7277988204c47d93367da187606
|
|
7
|
+
data.tar.gz: 5935c97005443167ccacf3f1c06a3fca275e6250f1549f5c3e9da05b20650cd96b87600185cf1c887a3474536446a30a33123dcf7d50a0a26dde359391f29cc9
|
data/.gitignore
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
/.config
|
|
4
|
+
/coverage/
|
|
5
|
+
/InstalledFiles
|
|
6
|
+
/pkg/
|
|
7
|
+
/spec/reports/
|
|
8
|
+
/test/tmp/
|
|
9
|
+
/test/version_tmp/
|
|
10
|
+
/tmp/
|
|
11
|
+
|
|
12
|
+
## Specific to RubyMotion:
|
|
13
|
+
.dat*
|
|
14
|
+
.repl_history
|
|
15
|
+
build/
|
|
16
|
+
|
|
17
|
+
## Documentation cache and generated files:
|
|
18
|
+
/.yardoc/
|
|
19
|
+
/_yardoc/
|
|
20
|
+
/doc/
|
|
21
|
+
/rdoc/
|
|
22
|
+
|
|
23
|
+
## Environment normalisation:
|
|
24
|
+
/.bundle/
|
|
25
|
+
/lib/bundler/man/
|
|
26
|
+
|
|
27
|
+
# for a library or gem, you might want to ignore these files since the code is
|
|
28
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
29
|
+
# Gemfile.lock
|
|
30
|
+
.ruby-version
|
|
31
|
+
.ruby-gemset
|
|
32
|
+
|
|
33
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
34
|
+
.rvmrc
|
|
35
|
+
*.iml
|
data/.rakeTasks
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<Settings><!--This file was automatically generated by Ruby plugin.
|
|
3
|
+
You are allowed to:
|
|
4
|
+
1. Remove rake task
|
|
5
|
+
2. Add existing rake tasks
|
|
6
|
+
To add existing rake tasks automatically delete this file and reload the project.
|
|
7
|
+
--><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Builds all packages" fullCmd="build" taksId="build" /><RakeTask description="Spawns an Interactive Ruby Console" fullCmd="console" taksId="console" /><RakeTask description="Installs all built gem packages" fullCmd="install" taksId="install" /><RakeTask description="Performs a release" fullCmd="release" taksId="release" /><RakeTask description="Run RSpec code examples" fullCmd="spec" taksId="spec" /><RakeGroup description="" fullCmd="" taksId="build"><RakeTask description="" fullCmd="build:gce_metadata" taksId="gce_metadata" /><RakeTask description="" fullCmd="build:gem" taksId="gem" /><RakeGroup description="" fullCmd="" taksId="gem"><RakeTask description="" fullCmd="build:gem:gce_metadata" taksId="gce_metadata" /></RakeGroup></RakeGroup><RakeGroup description="" fullCmd="" taksId="console"><RakeTask description="" fullCmd="console:gce_metadata" taksId="gce_metadata" /></RakeGroup><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="gem" taksId="gem" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="" fullCmd="install:gce_metadata" taksId="gce_metadata" /></RakeGroup><RakeTask description="" fullCmd="install_gem" taksId="install_gem" /><RakeTask description="" fullCmd="package" taksId="package" /><RakeTask description="" fullCmd="pkg" taksId="pkg" /><RakeTask description="" fullCmd="pkg/gce_metadata-0.1.0.gem" taksId="pkg/gce_metadata-0.1.0.gem" /><RakeTask description="" fullCmd="publish" taksId="publish" /><RakeTask description="" fullCmd="push" taksId="push" /><RakeGroup description="" fullCmd="" taksId="push"><RakeTask description="" fullCmd="push:gce_metadata" taksId="gce_metadata" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="scm"><RakeTask description="" fullCmd="scm:push" taksId="push" /><RakeTask description="" fullCmd="scm:status" taksId="status" /><RakeTask description="" fullCmd="scm:tag" taksId="tag" /></RakeGroup><RakeTask description="" fullCmd="test" taksId="test" /><RakeTask description="" fullCmd="validate" taksId="validate" /></RakeGroup></Settings>
|
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--colour --format documentation
|
data/.travis.yml
ADDED
data/ChangeLog.md
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
gce-metadata (0.1.1)
|
|
5
|
+
awesome_print
|
|
6
|
+
ec2-metadata (~> 0.2, >= 0.2.2)
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
awesome_print (1.6.1)
|
|
12
|
+
diff-lcs (1.2.5)
|
|
13
|
+
ec2-metadata (0.2.2)
|
|
14
|
+
rake (10.5.0)
|
|
15
|
+
rspec (3.4.0)
|
|
16
|
+
rspec-core (~> 3.4.0)
|
|
17
|
+
rspec-expectations (~> 3.4.0)
|
|
18
|
+
rspec-mocks (~> 3.4.0)
|
|
19
|
+
rspec-core (3.4.2)
|
|
20
|
+
rspec-support (~> 3.4.0)
|
|
21
|
+
rspec-expectations (3.4.0)
|
|
22
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
23
|
+
rspec-support (~> 3.4.0)
|
|
24
|
+
rspec-mocks (3.4.1)
|
|
25
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
26
|
+
rspec-support (~> 3.4.0)
|
|
27
|
+
rspec-support (3.4.1)
|
|
28
|
+
rubygems-tasks (0.2.4)
|
|
29
|
+
|
|
30
|
+
PLATFORMS
|
|
31
|
+
ruby
|
|
32
|
+
|
|
33
|
+
DEPENDENCIES
|
|
34
|
+
bundler (~> 1.10)!
|
|
35
|
+
gce-metadata!
|
|
36
|
+
rake (~> 10.0)!
|
|
37
|
+
rspec (~> 3.0)!
|
|
38
|
+
rubygems-tasks (~> 0.2)!
|
|
39
|
+
|
|
40
|
+
BUNDLED WITH
|
|
41
|
+
1.11.2
|
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2015, DLD Internet, Inc.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# gce-metadata
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
$ [sudo] gem install gce-metadata
|
|
5
|
+
|
|
6
|
+
## As ruby library
|
|
7
|
+
gce-metadata provides a way to access meta-data and user-data on GCE instance.
|
|
8
|
+
|
|
9
|
+
GCEMetadata[:instance_id]
|
|
10
|
+
GCEMetadata['instance_id']
|
|
11
|
+
GCEMetadata[:'instance-id']
|
|
12
|
+
GCEMetadata['instance-id']
|
|
13
|
+
|
|
14
|
+
If you want to specify API version, you can get data like this:
|
|
15
|
+
GCEMetadata['1.0'][:instance_id]
|
|
16
|
+
|
|
17
|
+
If you can also get it like this:
|
|
18
|
+
GCEMetadata['1.0']['meta-data'][:instance_id]
|
|
19
|
+
|
|
20
|
+
For more detail, see also:
|
|
21
|
+
http://github.com/akm/gce-metadata/blob/master/spec/introduction_spec.rb
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## As a command
|
|
25
|
+
gce-metadata shows various meta-data and user-data
|
|
26
|
+
$ gce-metadata
|
|
27
|
+
|
|
28
|
+
For more detail, type
|
|
29
|
+
$ gce-metadata -h
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## Dummy YAML
|
|
33
|
+
If you want to access meta-data or user-data not on GCE Instance like on it,
|
|
34
|
+
make one of these files
|
|
35
|
+
./config/gce_metadata.yml
|
|
36
|
+
./gce_metadata.yml
|
|
37
|
+
~/gce_metadata.yml
|
|
38
|
+
/etc/gce_metadata.yml
|
|
39
|
+
|
|
40
|
+
Dummy YAML file must be like output of gce-metadata on GCE instance.
|
|
41
|
+
You can export it on GCE instance like this:
|
|
42
|
+
$ gce-medatata > gce_metadata.yml
|
|
43
|
+
$ cp gce_metadata.yml /path/to/dir/for/non/gce/instance
|
|
44
|
+
|
|
45
|
+
Or if you don't have GCE instance, you can get an example by
|
|
46
|
+
$ gce-metadata -d
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Note on Patches/Pull Requests
|
|
50
|
+
|
|
51
|
+
* Fork the project.
|
|
52
|
+
* Make your feature addition or bug fix.
|
|
53
|
+
* Add tests for it. This is important so I don't break it in a
|
|
54
|
+
future version unintentionally.
|
|
55
|
+
* Commit, do not mess with rakefile, version, or history.
|
|
56
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
|
57
|
+
* Send me a pull request. Bonus points for topic branches.
|
|
58
|
+
|
|
59
|
+
## Copyright
|
|
60
|
+
|
|
61
|
+
Copyright (c) 2015 DLD Internet, Inc. See LICENSE for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require 'bundler/setup'
|
|
7
|
+
rescue LoadError => e
|
|
8
|
+
abort e.message
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require 'rake'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
require 'rubygems/tasks'
|
|
15
|
+
Gem::Tasks.new
|
|
16
|
+
|
|
17
|
+
require 'rspec/core/rake_task'
|
|
18
|
+
RSpec::Core::RakeTask.new
|
|
19
|
+
|
|
20
|
+
task :test => :spec
|
|
21
|
+
task :default => :spec
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require 'gce_metadata/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |gem|
|
|
8
|
+
gem.name = "gce-metadata"
|
|
9
|
+
gem.version = GCEMetadata::VERSION
|
|
10
|
+
gem.summary = %q{gce-metadata provides access to GCE instance metadata}
|
|
11
|
+
gem.description = %q{gce-metadata provides access to GCE instance metadata.}
|
|
12
|
+
gem.license = "MIT"
|
|
13
|
+
gem.authors = ["Christo De Lange"]
|
|
14
|
+
gem.email = "rubygems@dldinternet.com"
|
|
15
|
+
gem.homepage = "http://github.com/dldinternet/gce-metadata"
|
|
16
|
+
|
|
17
|
+
gem.files = `git ls-files`.split($/)
|
|
18
|
+
|
|
19
|
+
`git submodule --quiet foreach --recursive pwd`.split($/).each do |submodule|
|
|
20
|
+
submodule.sub!("#{Dir.pwd}/",'')
|
|
21
|
+
|
|
22
|
+
Dir.chdir(submodule) do
|
|
23
|
+
`git ls-files`.split($/).map do |subpath|
|
|
24
|
+
gem.files << File.join(submodule,subpath)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
29
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
30
|
+
gem.require_paths = ['lib']
|
|
31
|
+
|
|
32
|
+
gem.add_dependency 'ec2-metadata', '~> 0.2', '>= 0.2.2'
|
|
33
|
+
gem.add_dependency 'awesome_print' #, '~> 1.2'
|
|
34
|
+
|
|
35
|
+
gem.add_development_dependency 'bundler', '~> 1.10'
|
|
36
|
+
gem.add_development_dependency 'rake', '~> 10.0'
|
|
37
|
+
gem.add_development_dependency 'rspec', '~> 3.0'
|
|
38
|
+
gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
|
|
39
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
require 'gce_metadata'
|
|
2
|
+
|
|
3
|
+
module GCEMetadata
|
|
4
|
+
class Base
|
|
5
|
+
|
|
6
|
+
attr_reader :path
|
|
7
|
+
attr_reader :default_child_key
|
|
8
|
+
|
|
9
|
+
def initialize(path, default_child_key = nil)
|
|
10
|
+
@path = path
|
|
11
|
+
@default_child_key = default_child_key
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def children
|
|
15
|
+
@children ||= {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def child_keys
|
|
19
|
+
unless defined?(@child_keys)
|
|
20
|
+
lines = GCEMetadata.get("#{path}").split(/$/).map(&:strip).select{|l| not (l.nil? or l.empty?)} # .map{|l| l.gsub!(%r'/$','')}
|
|
21
|
+
leaves = lines.select{|line| line =~ %r'[^/]$'}
|
|
22
|
+
@child_keys = lines
|
|
23
|
+
if leaves.size > 0
|
|
24
|
+
@child_names = {}
|
|
25
|
+
leaves.each do |key|
|
|
26
|
+
name = get(key)
|
|
27
|
+
name = name.match(/^\[.*?\]$/) ? (eval name rescue name) : name
|
|
28
|
+
@child_names[key] = name
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
@child_keys
|
|
33
|
+
end
|
|
34
|
+
alias_method :keys, :child_keys
|
|
35
|
+
|
|
36
|
+
def get(child_key)
|
|
37
|
+
logging("#{self.class.name}.get(#{child_key.inspect})") do
|
|
38
|
+
child_key = GCEMetadata.formalize_key(child_key)
|
|
39
|
+
if children.has_key?(child_key)
|
|
40
|
+
result = children[child_key]
|
|
41
|
+
else
|
|
42
|
+
if is_child_key?(child_key)
|
|
43
|
+
result = is_struct?(child_key) ?
|
|
44
|
+
new_child(child_key) :
|
|
45
|
+
GCEMetadata.get("#{path}#{child_key}")
|
|
46
|
+
unless result
|
|
47
|
+
if is_child_key?("#{child_key}/")
|
|
48
|
+
child_key = "#{child_key}/"
|
|
49
|
+
result = is_struct?(child_key) ?
|
|
50
|
+
new_child(child_key) :
|
|
51
|
+
GCEMetadata.get("#{path}#{child_key}")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
raise NotFoundError, "#{path}#{child_key} not found as default key" if @getting_default_child
|
|
56
|
+
raise NotFoundError, "#{path}#{child_key} not found" unless default_child
|
|
57
|
+
result = default_child.get(child_key)
|
|
58
|
+
end
|
|
59
|
+
children[child_key] = result
|
|
60
|
+
end
|
|
61
|
+
result
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
alias_method :[], :get
|
|
65
|
+
|
|
66
|
+
def is_child_key?(key)
|
|
67
|
+
exp = /^#{key.gsub(%r'([^/])$', '\1/')}?$/
|
|
68
|
+
child_keys.any?{|child_key| child_key =~ exp}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def is_struct?(child_key)
|
|
72
|
+
k = GCEMetadata.formalize_key(child_key)
|
|
73
|
+
#k << '/' unless k.match(%r'/$')
|
|
74
|
+
k.match(%r'/$') || (defined?(@child_names) && @child_names.keys.include?(child_key))
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def new_child(child_key)
|
|
78
|
+
if defined?(@child_names) && (name = @child_names[child_key])
|
|
79
|
+
grandchild = Base.new("#{path}#{child_key}/")
|
|
80
|
+
child = Base.new("#{path}#{child_key}/")
|
|
81
|
+
child.instance_variable_set(:@children, {name => grandchild})
|
|
82
|
+
child.instance_variable_set(:@child_keys, [name])
|
|
83
|
+
child
|
|
84
|
+
else
|
|
85
|
+
Base.new("#{path}#{child_key}")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
alias_method :[], :get
|
|
90
|
+
|
|
91
|
+
def default_child
|
|
92
|
+
return @default_child if @default_child
|
|
93
|
+
logging("default_child") do
|
|
94
|
+
if default_child_key
|
|
95
|
+
@getting_default_child = true
|
|
96
|
+
begin
|
|
97
|
+
@default_child = get(default_child_key)
|
|
98
|
+
ensure
|
|
99
|
+
@getting_default_child = false
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def to_hash
|
|
106
|
+
keys.inject({}) do |dest, key|
|
|
107
|
+
value = get(key)
|
|
108
|
+
key = key.sub(/\/$/, '')
|
|
109
|
+
dest[key] = value.respond_to?(:to_hash) ? value.to_hash : value
|
|
110
|
+
dest
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def from_hash(hash)
|
|
115
|
+
hash = hash.inject({}){|d, (k, v)| d[GCEMetadata.formalize_key(k)] = v; d}
|
|
116
|
+
@child_keys = hash.keys
|
|
117
|
+
@children = {}
|
|
118
|
+
hash.each do |key, value|
|
|
119
|
+
if value.is_a?(Array)
|
|
120
|
+
idx = 0
|
|
121
|
+
value = value.inject({}){|d, v| d[idx] = v; idx += 1; d}
|
|
122
|
+
end
|
|
123
|
+
if value.is_a?(Hash)
|
|
124
|
+
child = new_child(key)
|
|
125
|
+
@children[key] = child
|
|
126
|
+
child.from_hash(value)
|
|
127
|
+
else
|
|
128
|
+
@children[key] = value
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
private
|
|
135
|
+
def logging(msg, &block)
|
|
136
|
+
GCEMetadata.logging(msg, &block)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require 'ec2_metadata'
|
|
3
|
+
require 'hash_key_orderable'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
require 'awesome_print'
|
|
6
|
+
|
|
7
|
+
module GCEMetadata
|
|
8
|
+
module Command
|
|
9
|
+
class << self
|
|
10
|
+
DATA_KEY_ORDER = %w(instance project)
|
|
11
|
+
META_DATA_KEY_ORDER =
|
|
12
|
+
%w( attributes
|
|
13
|
+
cpu-platform
|
|
14
|
+
description
|
|
15
|
+
disks
|
|
16
|
+
hostname
|
|
17
|
+
id
|
|
18
|
+
image
|
|
19
|
+
licenses
|
|
20
|
+
machine-type
|
|
21
|
+
maintenance-event
|
|
22
|
+
network-interfaces
|
|
23
|
+
scheduling
|
|
24
|
+
service-accounts
|
|
25
|
+
tags
|
|
26
|
+
virtual-clock
|
|
27
|
+
zone
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def show(api_version = 'v1')
|
|
31
|
+
timeout do
|
|
32
|
+
v = (api_version || '').strip
|
|
33
|
+
keys = GCEMetadata.instance.keys
|
|
34
|
+
unless keys.include?(v.gsub(%r'([^/])$', '\1/'))
|
|
35
|
+
puts("#{self.class.name}.instance.keys\n#{keys.ai}")
|
|
36
|
+
raise ArgumentError, "API version must be one of #{GCEMetadata.instance.keys.inspect} but was #{api_version.inspect}"
|
|
37
|
+
end
|
|
38
|
+
show_yaml_path_if_loaded
|
|
39
|
+
data = GCEMetadata.instance.to_hash
|
|
40
|
+
data = data[v]
|
|
41
|
+
data.extend(HashKeyOrderable)
|
|
42
|
+
data.key_order = DATA_KEY_ORDER
|
|
43
|
+
meta_data = data['instance']
|
|
44
|
+
meta_data.extend(HashKeyOrderable)
|
|
45
|
+
meta_data.key_order = META_DATA_KEY_ORDER
|
|
46
|
+
puts YAML.dump(data)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def show_api_versions
|
|
51
|
+
timeout do
|
|
52
|
+
show_yaml_path_if_loaded
|
|
53
|
+
puts GCEMetadata.instance.keys
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def show_dummy_yaml
|
|
58
|
+
show_yaml_path_if_loaded
|
|
59
|
+
puts IO.read(File.expand_path(File.join(File.dirname(__FILE__), 'dummy.yml')))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
def timeout
|
|
64
|
+
begin
|
|
65
|
+
yield
|
|
66
|
+
rescue Timeout::Error, SystemCallError => error
|
|
67
|
+
puts "HTTP request timed out. You can use dummy YAML for non GCE Instance. #{Dummy.yaml_paths.inspect}"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def show_yaml_path_if_loaded
|
|
72
|
+
if path = GCEMetadata::Dummy.loaded_yaml_path
|
|
73
|
+
puts "Actually these data is based on a DUMMY yaml file: #{path}"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
module GCEMetadata
|
|
5
|
+
module Dummy
|
|
6
|
+
YAML_FILENAME = 'gce_metadata.yml'.freeze
|
|
7
|
+
YAML_SEARCH_DIRS = ['./config', '.', '~', '/etc'].freeze
|
|
8
|
+
ENV_SPECIFIED_PATH = "GCE_METADATA_DUMMY_YAML".freeze
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def yaml_paths
|
|
12
|
+
dirs = YAML_SEARCH_DIRS.dup
|
|
13
|
+
if Module.constants.include?('RAILS_ROOT')
|
|
14
|
+
dirs.unshift(File.join(Module.const_get('RAILS_ROOT'), 'config'))
|
|
15
|
+
end
|
|
16
|
+
result = dirs.map{|d| File.join(d, YAML_FILENAME)}
|
|
17
|
+
if (specified_path = ENV[ENV_SPECIFIED_PATH])
|
|
18
|
+
result.unshift(specified_path)
|
|
19
|
+
end
|
|
20
|
+
result
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def search_and_load_yaml
|
|
24
|
+
paths = Dir.glob(yaml_paths.map{|path| File.expand_path(path) rescue nil}.compact)
|
|
25
|
+
load_yaml(paths.first) unless paths.empty?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def load_yaml(path)
|
|
29
|
+
erb = ERB.new(IO.read(path))
|
|
30
|
+
erb.filename = path
|
|
31
|
+
text = erb.result
|
|
32
|
+
GCEMetadata.from_hash(YAML.load(text))
|
|
33
|
+
@loaded_yaml_path = path
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def loaded_yaml_path
|
|
37
|
+
@loaded_yaml_path
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta-data:
|
|
3
|
+
ami-id: ami-6966372c
|
|
4
|
+
ami-launch-index: "0"
|
|
5
|
+
ami-manifest-path: akm2000-us-west-1/dev-20100406-01.manifest.xml
|
|
6
|
+
ancestor-ami-ids: ami-c32e7f86
|
|
7
|
+
instance-id: i-3de0f678
|
|
8
|
+
instance-type: m1.small
|
|
9
|
+
instance-action: none
|
|
10
|
+
security-groups: |-
|
|
11
|
+
ruby-dev
|
|
12
|
+
default
|
|
13
|
+
hostname: ip-10-160-115-246.us-west-1.compute.internal
|
|
14
|
+
public-hostname: ec2-204-236-178-101.us-west-1.compute.amazonaws.com
|
|
15
|
+
public-ipv4: 204.236.178.101
|
|
16
|
+
local-hostname: ip-10-160-115-246.us-west-1.compute.internal
|
|
17
|
+
local-ipv4: 10.160.115.246
|
|
18
|
+
kernel-id: aki-773c6d32
|
|
19
|
+
ramdisk-id: ari-c12e7f84
|
|
20
|
+
reservation-id: r-b76769f2
|
|
21
|
+
block-device-mapping:
|
|
22
|
+
root: /dev/sda1
|
|
23
|
+
ami: sda1
|
|
24
|
+
swap: sda3
|
|
25
|
+
ephemeral0: sda2
|
|
26
|
+
public-keys:
|
|
27
|
+
"0":
|
|
28
|
+
west-dev01:
|
|
29
|
+
openssh-key: |
|
|
30
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3on58pV0jEdOukPJMi3zaI90Vg5n+vTaWVNBC2pDfaFX5yVIwcT/LQn9CqvcFsayvRaLfrVT8+wz7BnvQwldUAoIC5wCb5MXhhdr+3dk3ey/t8t3rS0lO6pxYc1jchkH23C/RQz+gOzFDuuzxX4zngRRkajYt1hKEVOPLVv9tqBawalCF0d3iALu/XBguj6fUogaqHgNgZZpZXTXDyfmLtWnXErB0/hqmuV6iIXjclB+K94lZCcJaOQSm/+9C6R0jCKwJNteJInvD553IzyTzBgc5Os3ukNuYv+Ub6aP717ikmI5fa5P0pBL+684kkPKvpGoADJveACoL1+uKpk0j west-dev01
|
|
31
|
+
|
|
32
|
+
placement:
|
|
33
|
+
availability-zone: us-west-1b
|
|
34
|
+
user-data:
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'gce_metadata'
|
|
2
|
+
|
|
3
|
+
module GCEMetadata
|
|
4
|
+
module HttpClient
|
|
5
|
+
def self.extended(obj)
|
|
6
|
+
obj.open_timeout_sec ||= DEFAULT_OPEN_TIMEOUT
|
|
7
|
+
obj.read_timeout_sec ||= DEFAULT_READ_TIMEOUT
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
DEFAULT_OPEN_TIMEOUT = 5
|
|
11
|
+
DEFAULT_READ_TIMEOUT = 10
|
|
12
|
+
|
|
13
|
+
attr_accessor :open_timeout_sec
|
|
14
|
+
attr_accessor :read_timeout_sec
|
|
15
|
+
|
|
16
|
+
def get(path)
|
|
17
|
+
logging("GCEMetadata.get(#{path.inspect})") do
|
|
18
|
+
http = Net::HTTP.new(DEFAULT_HOST)
|
|
19
|
+
http.open_timeout = self.open_timeout_sec
|
|
20
|
+
http.read_timeout = self.read_timeout_sec
|
|
21
|
+
http.start do |http|
|
|
22
|
+
res = http.get(path, 'Metadata-Flavor' => 'Google')
|
|
23
|
+
res.is_a?(Net::HTTPSuccess) ? res.body : nil
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'gce_metadata'
|
|
2
|
+
|
|
3
|
+
module GCEMetadata
|
|
4
|
+
class Revision < Base
|
|
5
|
+
def initialize(path)
|
|
6
|
+
@path = path
|
|
7
|
+
@default_child_key = 'v1/'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def new_child(child_key)
|
|
11
|
+
logging("new_child(#{child_key.inspect})") do
|
|
12
|
+
child_path = "#{path}#{child_key}"
|
|
13
|
+
child_path << '/' if (is_struct?(child_key) and not child_key.match(%r'/$'))
|
|
14
|
+
Base.new(child_path)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def is_struct?(child_key)
|
|
19
|
+
child_key =~ /\/$/
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'ec2_metadata'
|
|
2
|
+
|
|
3
|
+
module GCEMetadata
|
|
4
|
+
class Root < Base
|
|
5
|
+
def initialize(path = '/')
|
|
6
|
+
@path = path
|
|
7
|
+
@default_child_key = 'v1'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def new_child(child_key)
|
|
11
|
+
logging("new_child(#{child_key.inspect})") do
|
|
12
|
+
Revision.new("#{path}#{child_key}/")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def is_struct?(child_key)
|
|
17
|
+
true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/gce_metadata.rb
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'gce_metadata/version'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
Net::HTTP.version_1_2
|
|
4
|
+
require 'ec2_metadata'
|
|
5
|
+
|
|
6
|
+
module GCEMetadata
|
|
7
|
+
DEFAULT_HOST = "metadata.google.internal".freeze
|
|
8
|
+
DEFAULT_REVISION = 'v1'
|
|
9
|
+
|
|
10
|
+
autoload :HttpClient, 'gce_metadata/http_client'
|
|
11
|
+
autoload :Base, 'gce_metadata/base'
|
|
12
|
+
autoload :Root, 'gce_metadata/root'
|
|
13
|
+
autoload :Revision, 'gce_metadata/revision'
|
|
14
|
+
autoload :Dummy, 'gce_metadata/dummy'
|
|
15
|
+
autoload :Command, 'gce_metadata/command'
|
|
16
|
+
|
|
17
|
+
# include Ec2Metadata
|
|
18
|
+
extend HttpClient
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def instance
|
|
22
|
+
@instance ||= Root.new['computeMetadata']
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def clear_instance
|
|
26
|
+
@instance = nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def [](key)
|
|
30
|
+
instance[key]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def to_hash(revision = DEFAULT_REVISION)
|
|
34
|
+
self[revision].to_hash
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def from_hash(hash, revision = DEFAULT_REVISION)
|
|
38
|
+
# hash = {revision => hash}
|
|
39
|
+
# instance.from_hash(hash)
|
|
40
|
+
rev_obj = instance.new_child(revision)
|
|
41
|
+
instance.instance_variable_set(:@children, {revision => rev_obj})
|
|
42
|
+
instance.instance_variable_set(:@child_keys, [revision])
|
|
43
|
+
rev_obj.from_hash(hash)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def formalize_key(key)
|
|
47
|
+
#key.to_s.gsub(/_/, '-')
|
|
48
|
+
key
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def logging(msg)
|
|
52
|
+
@indent ||= 0
|
|
53
|
+
disp = (" " * @indent) << msg
|
|
54
|
+
# puts(disp)
|
|
55
|
+
@indent += 2
|
|
56
|
+
begin
|
|
57
|
+
result = yield
|
|
58
|
+
ensure
|
|
59
|
+
@indent -= 2
|
|
60
|
+
end
|
|
61
|
+
# puts "#{disp} => #{result.inspect}"
|
|
62
|
+
result
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class NotFoundError < StandardError
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
unless ENV['GCE_METADATA_DUMMY_DISABLED'] =~ /yes|true|on/i
|
|
72
|
+
GCEMetadata::Dummy.search_and_load_yaml
|
|
73
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: gce-metadata
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Christo De Lange
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-02-03 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: ec2-metadata
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.2'
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 0.2.2
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - "~>"
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '0.2'
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 0.2.2
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: awesome_print
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
type: :runtime
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: bundler
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.10'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.10'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: rake
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '10.0'
|
|
68
|
+
type: :development
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '10.0'
|
|
75
|
+
- !ruby/object:Gem::Dependency
|
|
76
|
+
name: rspec
|
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '3.0'
|
|
82
|
+
type: :development
|
|
83
|
+
prerelease: false
|
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '3.0'
|
|
89
|
+
- !ruby/object:Gem::Dependency
|
|
90
|
+
name: rubygems-tasks
|
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0.2'
|
|
96
|
+
type: :development
|
|
97
|
+
prerelease: false
|
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0.2'
|
|
103
|
+
description: gce-metadata provides access to GCE instance metadata.
|
|
104
|
+
email: rubygems@dldinternet.com
|
|
105
|
+
executables: []
|
|
106
|
+
extensions: []
|
|
107
|
+
extra_rdoc_files: []
|
|
108
|
+
files:
|
|
109
|
+
- ".gitignore"
|
|
110
|
+
- ".rakeTasks"
|
|
111
|
+
- ".rspec"
|
|
112
|
+
- ".travis.yml"
|
|
113
|
+
- ChangeLog.md
|
|
114
|
+
- Gemfile
|
|
115
|
+
- Gemfile.lock
|
|
116
|
+
- LICENSE
|
|
117
|
+
- README.md
|
|
118
|
+
- Rakefile
|
|
119
|
+
- gce_metadata.gemspec
|
|
120
|
+
- lib/gce_metadata.rb
|
|
121
|
+
- lib/gce_metadata/base.rb
|
|
122
|
+
- lib/gce_metadata/command.rb
|
|
123
|
+
- lib/gce_metadata/dummy.rb
|
|
124
|
+
- lib/gce_metadata/dummy.yml
|
|
125
|
+
- lib/gce_metadata/http_client.rb
|
|
126
|
+
- lib/gce_metadata/revision.rb
|
|
127
|
+
- lib/gce_metadata/root.rb
|
|
128
|
+
- lib/gce_metadata/version.rb
|
|
129
|
+
- spec/gce-metadata.rb
|
|
130
|
+
- spec/gce_metadata_spec.rb
|
|
131
|
+
- spec/spec_helper.rb
|
|
132
|
+
homepage: http://github.com/dldinternet/gce-metadata
|
|
133
|
+
licenses:
|
|
134
|
+
- MIT
|
|
135
|
+
metadata: {}
|
|
136
|
+
post_install_message:
|
|
137
|
+
rdoc_options: []
|
|
138
|
+
require_paths:
|
|
139
|
+
- lib
|
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ">="
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
|
+
requirements:
|
|
147
|
+
- - ">="
|
|
148
|
+
- !ruby/object:Gem::Version
|
|
149
|
+
version: '0'
|
|
150
|
+
requirements: []
|
|
151
|
+
rubyforge_project:
|
|
152
|
+
rubygems_version: 2.4.8
|
|
153
|
+
signing_key:
|
|
154
|
+
specification_version: 4
|
|
155
|
+
summary: gce-metadata provides access to GCE instance metadata
|
|
156
|
+
test_files:
|
|
157
|
+
- spec/gce-metadata.rb
|
|
158
|
+
- spec/gce_metadata_spec.rb
|
|
159
|
+
- spec/spec_helper.rb
|