loe-iclassify-interface 1.0.0

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.
data/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ === 1.0.0 / 2008-12-08
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
data/Manifest.txt ADDED
@@ -0,0 +1,11 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ iclassify-interface.gemspec
6
+ lib/iclassify-interface.rb
7
+ lib/iclassify-interface/agent.rb
8
+ lib/iclassify-interface/client.rb
9
+ lib/iclassify-interface/node.rb
10
+ lib/iclassify-interface/version.rb
11
+ test/test_iclassify-interface.rb
data/README.txt ADDED
@@ -0,0 +1,36 @@
1
+ = iclassify-interface
2
+
3
+ http://github.com/loe/iclassify-interface
4
+
5
+ == DESCRIPTION:
6
+
7
+ Module for interfacing with iclassify.
8
+
9
+ == INSTALL:
10
+
11
+ sudo gem install loe-iclassify-interface
12
+
13
+ == LICENSE:
14
+
15
+ (The MIT License)
16
+
17
+ Copyright (c) 2008 FIX
18
+
19
+ Permission is hereby granted, free of charge, to any person obtaining
20
+ a copy of this software and associated documentation files (the
21
+ 'Software'), to deal in the Software without restriction, including
22
+ without limitation the rights to use, copy, modify, merge, publish,
23
+ distribute, sublicense, and/or sell copies of the Software, and to
24
+ permit persons to whom the Software is furnished to do so, subject to
25
+ the following conditions:
26
+
27
+ The above copyright notice and this permission notice shall be
28
+ included in all copies or substantial portions of the Software.
29
+
30
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
31
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
34
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
35
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
36
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+
4
+ LIB_DIR = File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
5
+ $LOAD_PATH << LIB_DIR
6
+
7
+ require 'iclassify-interface/version'
8
+
9
+ HOE = Hoe.new('iclassify-interface', IClassify::VERSION) do |p|
10
+ p.name = "iclassify-interface"
11
+ p.author = "W. Andrew Loe III"
12
+ p.email = "loe@onehub.com"
13
+ p.summary = "Module for interfacing with an iclassify server."
14
+ end
15
+
16
+ # Cribbed from nokogiri
17
+ namespace :gem do
18
+ task :spec do
19
+ File.open("#{HOE.name}.gemspec", 'w') do |f|
20
+ f.write(HOE.spec.to_ruby)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{iclassify-interface}
3
+ s.version = "1.0.0"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["W. Andrew Loe III"]
7
+ s.date = %q{2008-12-08}
8
+ s.description = %q{Module for interfacing with iclassify.}
9
+ s.email = %q{loe@onehub.com}
10
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
11
+ s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "iclassify-interface.gemspec", "lib/iclassify-interface.rb", "lib/iclassify-interface/agent.rb", "lib/iclassify-interface/client.rb", "lib/iclassify-interface/node.rb", "lib/iclassify-interface/version.rb", "test/test_iclassify-interface.rb"]
12
+ s.has_rdoc = true
13
+ s.homepage = %q{http://github.com/loe/iclassify-interface}
14
+ s.rdoc_options = ["--main", "README.txt"]
15
+ s.require_paths = ["lib"]
16
+ s.rubyforge_project = %q{iclassify-interface}
17
+ s.rubygems_version = %q{1.2.0}
18
+ s.summary = %q{Module for interfacing with an iclassify server.}
19
+ s.test_files = ["test/test_iclassify-interface.rb"]
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 2
24
+
25
+ if current_version >= 3 then
26
+ s.add_development_dependency(%q<hoe>, [">= 1.8.2"])
27
+ else
28
+ s.add_dependency(%q<hoe>, [">= 1.8.2"])
29
+ end
30
+ else
31
+ s.add_dependency(%q<hoe>, [">= 1.8.2"])
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ require 'iclassify-interface/agent'
2
+ require 'iclassify-interface/client'
3
+ require 'iclassify-interface/node'
4
+ require 'iclassify-interface/version'
@@ -0,0 +1,155 @@
1
+ require 'rubygems'
2
+ require 'uuidtools'
3
+
4
+ module IClassify
5
+ class Agent
6
+ attr_accessor :node
7
+ attr_accessor :uuid
8
+ attr_accessor :password
9
+
10
+ #
11
+ # Create a new Agent. Takes a path to a file to either read or drop
12
+ # a UUID, and a server URL.
13
+ #
14
+ def initialize(uuidfile="/etc/icagent/icagent.uuid", server_url="http://localhost:3000")
15
+ @uuid = nil
16
+ @password = nil
17
+ if File.exists?(uuidfile)
18
+ IO.foreach(uuidfile) do |line|
19
+ @uuid, @password = line.chomp.split("!")
20
+ end
21
+ unless @password
22
+ @password = random_password(30)
23
+ write_uuidfile(uuidfile)
24
+ end
25
+ else
26
+ @uuid = UUID.random_create
27
+ @password = random_password(30)
28
+ write_uuidfile(uuidfile)
29
+ end
30
+ @client = IClassify::Client.new(server_url, @uuid, @password)
31
+ end
32
+
33
+ #
34
+ # Loads data about this node from the iClassify service
35
+ #
36
+ def load
37
+ begin
38
+ @node = @client.get_node(@uuid)
39
+ rescue Net::HTTPServerException => e
40
+ if e.to_s =~ /^404/
41
+ @node = IClassify::Node.new()
42
+ @node.description = "New Node"
43
+ @node.tags << "unclassified"
44
+ @node.password = @password
45
+ @node.uuid = @uuid
46
+ else
47
+ throw(e)
48
+ end
49
+ end
50
+ end
51
+
52
+ #
53
+ # Updates this node in the iClassify service.
54
+ #
55
+ def update
56
+ if @node.description == "New Node"
57
+ hostname = attrib?("hostname")
58
+ hostname ||= "New Node"
59
+ @node.description = hostname
60
+ end
61
+ @client.update_node(@node)
62
+ end
63
+
64
+ #
65
+ # Deletes this node from the iClassify service.
66
+ #
67
+ def delete
68
+ @client.delete_node(@node)
69
+ end
70
+
71
+ #
72
+ # Returns the tag name if this node has that tag.
73
+ #
74
+ def tag?(tag)
75
+ @node.tag?(tag)
76
+ end
77
+
78
+ # Returns the values for this attribute, if it exists for this node. If
79
+ # there is only one, it will return it, if it's an array, you get the
80
+ # array. You have to check!
81
+ def attrib?(attrib)
82
+ @node.attrib?(attrib)
83
+ end
84
+
85
+ # Returns the current node as a string.
86
+ def to_s
87
+ @node.to_s
88
+ end
89
+
90
+ # Returns the value if the given attribute has a given attribute.
91
+ def attrib_has_value?(attrib, value)
92
+ na = @node.attribs.detect { |a| a[:name] == attrib }
93
+ if na
94
+ return na.values.detect { |v| v == value}
95
+ else
96
+ return nil
97
+ end
98
+ end
99
+
100
+ # Add a tag to this node.
101
+ def add_tag(tag)
102
+ load unless @node
103
+ @node.tags << tag
104
+ end
105
+
106
+ # Add an attribute to this node. Requires a name and either a string or
107
+ # array of values.
108
+ #
109
+ # Will be cumulative!
110
+ def add_attrib(name, values)
111
+ load unless @node
112
+ @node.attribs << { :name => name, :values => values.kind_of?(Array) ? values : [ values ] }
113
+ end
114
+
115
+ # Replace the attribute with the given name's values in place.
116
+ # Will add a new attribute if it needs to.
117
+ def replace_attrib(name, values)
118
+ exists = @node.attribs.detect { |a| a[:name] == name }
119
+ if exists
120
+ exists[:values] = values.kind_of?(Array) ? values : [ values ]
121
+ else
122
+ add_attrib(name, values)
123
+ end
124
+ end
125
+
126
+ # Set the description for the node
127
+ def description(value)
128
+ @node.description = value
129
+ end
130
+
131
+ # return the value of @node.description
132
+ def description?()
133
+ @node.description
134
+ end
135
+
136
+ # Run an iclassify script.
137
+ def run_script(scriptfile)
138
+ eval(IO.read(scriptfile))
139
+ end
140
+
141
+ protected
142
+ def random_password(len)
143
+ chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
144
+ newpass = ""
145
+ 1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
146
+ newpass
147
+ end
148
+
149
+ def write_uuidfile(uuidfile)
150
+ File.open(uuidfile, "w") do |file|
151
+ file.puts "#{@uuid}!#{@password}"
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,108 @@
1
+ require 'rubygems'
2
+ require 'net/https'
3
+ require 'rexml/document'
4
+ require 'uri'
5
+ require 'yaml'
6
+
7
+ module IClassify
8
+
9
+ class Client
10
+ UUID_REGEX = /^[[:xdigit:]]{8}[:-][[:xdigit:]]{4}[:-][[:xdigit:]]{4}[:-][[:xdigit:]]{4}[:-][[:xdigit:]]{12}$/
11
+
12
+ def initialize(service_url, username, password)
13
+ service_url = "#{service_url}/rest" unless service_url =~ /rest$/
14
+ @url = URI.parse(service_url)
15
+ @username = username
16
+ @password = password
17
+ end
18
+
19
+ def make_url(method, params)
20
+ params[:appid] = @appid
21
+ super method, params
22
+ end
23
+
24
+ def search(query, attribs=[])
25
+ raise ArgumentError, "Attributes must be given as a list!" unless attribs.kind_of?(Array)
26
+ querystring = "search"
27
+ querystring << "?q=#{URI.escape(query)}"
28
+ querystring << "&a=#{URI.escape(attribs.join(','))}" if attribs.length > 0
29
+ results = get_rest(querystring, "text/yaml")
30
+ node_array = YAML.load(results).collect { |n| IClassify::Node.new(:yaml, n) }
31
+ end
32
+
33
+ def get_node(node_id)
34
+ IClassify::Node.new(:xml, get_rest("nodes/#{node_id}"))
35
+ end
36
+
37
+ def update_node(node)
38
+ if node.node_id
39
+ put_rest("nodes/#{node.node_id}", node.to_xml)
40
+ else
41
+ post_rest("nodes", node.to_xml)
42
+ end
43
+ end
44
+
45
+ def delete_node(node)
46
+ delete_rest("nodes/#{node.node_id}")
47
+ end
48
+
49
+ private
50
+
51
+ def get_rest(path, accept="application/xml")
52
+ url = URI.parse("#{@url}/#{path}")
53
+ run_request(:GET, url, false, accept)
54
+ end
55
+
56
+ def delete_rest(path, accept="application/xml")
57
+ url = URI.parse("#{@url}/#{path}")
58
+ run_request(:DELETE, url, false, accept)
59
+ end
60
+
61
+ def post_rest(path, xml, accept="application/xml")
62
+ url = URI.parse("#{@url}/#{path}")
63
+ run_request(:POST, url, xml, accept)
64
+ end
65
+
66
+ def put_rest(path, xml, accept="application/xml")
67
+ url = URI.parse("#{@url}/#{path}")
68
+ run_request(:PUT, url, xml, accept)
69
+ end
70
+
71
+ def run_request(method, url, data=false, accept="application/xml")
72
+ http = Net::HTTP.new(url.host, url.port)
73
+ if url.scheme == "https"
74
+ http.use_ssl = true
75
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
76
+ end
77
+ http.read_timeout = 60
78
+ headers = {
79
+ 'Accept' => accept,
80
+ 'Content-Type' => accept
81
+ }
82
+ req = nil
83
+ case method
84
+ when :GET
85
+ req_path = "#{url.path}"
86
+ req_path << "?#{url.query}" if url.query
87
+ req = Net::HTTP::Get.new(req_path, headers)
88
+ when :POST
89
+ req = Net::HTTP::Post.new(url.path, headers)
90
+ req.body = data if data
91
+ when :PUT
92
+ req = Net::HTTP::Put.new(url.path, headers)
93
+ req.body = data if data
94
+ when :DELETE
95
+ req = Net::HTTP::Delete.new(url.path, headers)
96
+ end
97
+ req.basic_auth(@username, @password)
98
+ res = http.request(req)
99
+ case res
100
+ when Net::HTTPSuccess
101
+ res.body
102
+ else
103
+ res.error!
104
+ end
105
+ end
106
+
107
+ end
108
+ end
@@ -0,0 +1,134 @@
1
+ require 'rubygems'
2
+ require 'rexml/document'
3
+ require 'builder'
4
+ require 'yaml'
5
+ require 'digest/sha1'
6
+
7
+ module IClassify
8
+ class Node
9
+ attr_accessor :tags, :uuid, :description, :notes, :attribs, :node_id, :password
10
+
11
+ def initialize(type=:xml, data=nil)
12
+ from_xml(data) if type == :xml && data
13
+ from_yaml(data) if type == :yaml && data
14
+ @tags ||= Array.new
15
+ @attribs ||= Array.new
16
+ @password = nil
17
+ end
18
+
19
+ def to_xml
20
+ xml = Builder::XmlMarkup.new
21
+ output = xml.node do
22
+ xml.id(@node_id) if @node_id
23
+ xml.uuid(@uuid)
24
+ xml.password(@password) if @password
25
+ xml.description(@description)
26
+ xml.notes(@notes)
27
+ xml.tags do
28
+ @tags.sort.each do |tag|
29
+ xml.tag(tag)
30
+ end
31
+ end
32
+ xml.attribs do
33
+ @attribs.sort{ |a,b| a[:name] <=> b[:name] }.each do |attrib|
34
+ xml.attrib do
35
+ xml.name(attrib[:name])
36
+ xml.values do
37
+ attrib[:values].each do |v|
38
+ xml.value(v)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ output
46
+ end
47
+
48
+ def digest
49
+ Digest::SHA1.hexdigest(to_s())
50
+ end
51
+
52
+ #
53
+ # Returns the tag name if this node has that tag.
54
+ #
55
+ def tag?(tag)
56
+ @tags.detect { |t| t == tag }
57
+ end
58
+
59
+ # Returns the values for this attribute, if it exists for this node. If
60
+ # there is only one, it will return it, if it's an array, you get the
61
+ # array. You have to check!
62
+ def attrib?(attrib)
63
+ na = @attribs.detect { |a| a[:name] == attrib }
64
+ return nil unless na
65
+ if na[:values].length > 1
66
+ return na[:values]
67
+ else
68
+ return na[:values][0]
69
+ end
70
+ end
71
+
72
+ def to_s(tags=nil,attribs=[])
73
+ output = String.new
74
+ output << "uuid: #{@uuid}\n"
75
+ output << "node_id: #{@node_id}\n"
76
+ output << "notes: #{@notes}\n"
77
+ output << "description: #{@description}\n"
78
+ output << "tags: #{@tags.sort.join(' ')}\n"
79
+ output << "attribs:\n"
80
+ @attribs.select{ |attrib| attribs.include?(attrib[:name].to_sym) }.sort{ |a,b| a[:name] <=> b[:name] }.each do |attrib|
81
+ output << " #{attrib[:name]}: #{attrib[:values].join(', ')}\n"
82
+ end
83
+ output
84
+ end
85
+
86
+ def to_puppet
87
+ output = Hash.new
88
+ output["classes"] = @tags
89
+ output["parameters"] = Hash.new
90
+ @attribs.each do |attrib|
91
+ if attrib[:values].length > 1
92
+ output["parameters"][attrib[:name]] = attrib[:values]
93
+ else
94
+ output["parameters"][attrib[:name]] = attrib[:values][0]
95
+ end
96
+ end
97
+ output.to_yaml
98
+ end
99
+
100
+ def from_xml(doc)
101
+ xml = nil
102
+ if doc.kind_of?(REXML::Element)
103
+ xml = doc
104
+ else
105
+ xml = REXML::Document.new(doc)
106
+ end
107
+ @tags = Array.new
108
+ xml.elements.each('//tag') { |t| @tags << t.text }
109
+ @uuid = xml.get_text('//uuid')
110
+ @node_id = xml.get_text('//id')
111
+ @description = xml.get_text('//description')
112
+ @notes = xml.get_text('//notes')
113
+ @attribs = Array.new
114
+ xml.elements.each('//attrib') do |attrib|
115
+ cattrib = Hash.new
116
+ cattrib[:name] = attrib.get_text('name').to_s
117
+ value_array = Array.new
118
+ attrib.elements.each('values/value') { |v| value_array << v.text }
119
+ cattrib[:values] = value_array
120
+ @attribs << cattrib
121
+ end
122
+ end
123
+
124
+ def from_yaml(data)
125
+ @tags = data[:tags].collect { |t| t[:name] }
126
+ @uuid = data[:uuid]
127
+ @description = data[:description]
128
+ @notes = data[:notes]
129
+ @attribs = data[:attribs].delete_if { |x| x[:name] == "text" }
130
+ @node_id = data[:id]
131
+ end
132
+
133
+ end
134
+ end
@@ -0,0 +1,3 @@
1
+ module IClassify
2
+ VERSION = '1.0.0'
3
+ end
File without changes
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: loe-iclassify-interface
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - W. Andrew Loe III
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-08 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.8.2
23
+ version:
24
+ description: Module for interfacing with iclassify.
25
+ email: loe@onehub.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - History.txt
32
+ - Manifest.txt
33
+ - README.txt
34
+ files:
35
+ - History.txt
36
+ - Manifest.txt
37
+ - README.txt
38
+ - Rakefile
39
+ - iclassify-interface.gemspec
40
+ - lib/iclassify-interface.rb
41
+ - lib/iclassify-interface/agent.rb
42
+ - lib/iclassify-interface/client.rb
43
+ - lib/iclassify-interface/node.rb
44
+ - lib/iclassify-interface/version.rb
45
+ - test/test_iclassify-interface.rb
46
+ has_rdoc: true
47
+ homepage: http://github.com/loe/iclassify-interface
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --main
51
+ - README.txt
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project: iclassify-interface
69
+ rubygems_version: 1.2.0
70
+ signing_key:
71
+ specification_version: 2
72
+ summary: Module for interfacing with an iclassify server.
73
+ test_files:
74
+ - test/test_iclassify-interface.rb