ucslib 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +43 -4
- data/lib/ucslib/inventory.rb +2 -1
- data/lib/ucslib/manage.rb +61 -34
- data/lib/ucslib/stats.rb +83 -0
- data/lib/ucslib/version.rb +1 -1
- data/lib/ucslib.rb +1 -0
- metadata +3 -2
data/README.rdoc
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
-
= ucslib (
|
1
|
+
= ucslib (beta)
|
2
2
|
|
3
3
|
Ruby Client Library for Cisco UCS Manager that could be used by DevOps toolchains - Puppet or Chef and other custom tools - to provide MaaS (Metal-as-a-Service) for installing and running OpenStack, Hadoop, etc. ucslib accepts JSON as configuration for provisioning.
|
4
4
|
|
5
5
|
|
6
|
+
** Version 0.1.1 has been released **
|
7
|
+
|
8
|
+
Major changes:
|
9
|
+
|
10
|
+
1. Provision has set_ vs create_ methods. Please update your apps.
|
11
|
+
2. Added Manage functions to associate service profiles to server pools
|
12
|
+
|
6
13
|
== Install
|
7
14
|
|
8
15
|
gem install ucslib
|
@@ -71,14 +78,46 @@ VLAN: 200 with name: OpenStack-Mgmt
|
|
71
78
|
=> 0
|
72
79
|
1.9.3p194 :016 >
|
73
80
|
|
74
|
-
|
75
|
-
|
81
|
+
1.9.3p194 :016 > ucs_stats = UCSStats.new
|
82
|
+
|
83
|
+
1.9.3p194 :017 > statsxml = ucs_stats.fetch(token_json)
|
84
|
+
|
85
|
+
1.9.3p194 :017 > ucs.show_sample(statsml,'fcStats')
|
86
|
+
|
87
|
+
The attributes for fcStats for dn=sys/switch-B/slot-1/switch-fc/port-32/stats are:
|
88
|
+
bytesRx = 125283780333316
|
89
|
+
bytesRxDelta = 142669360
|
90
|
+
bytesRxDeltaAvg = 142706128
|
91
|
+
bytesRxDeltaMax = 146404048
|
92
|
+
bytesRxDeltaMin = 139044968
|
93
|
+
bytesTx = 42023875724480
|
94
|
+
bytesTxDelta = 29946840
|
95
|
+
bytesTxDeltaAvg = 29842170
|
96
|
+
bytesTxDeltaMax = 31907484
|
97
|
+
bytesTxDeltaMin = 27672184
|
98
|
+
intervals = 58982460
|
99
|
+
packetsRx = 67694612103
|
100
|
+
packetsRxDelta = 78357
|
101
|
+
packetsRxDeltaAvg = 78476
|
102
|
+
packetsRxDeltaMax = 80258
|
103
|
+
packetsRxDeltaMin = 76814
|
104
|
+
packetsTx = 22997688197
|
105
|
+
packetsTxDelta = 18346
|
106
|
+
packetsTxDeltaAvg = 18318
|
107
|
+
packetsTxDeltaMax = 19393
|
108
|
+
packetsTxDeltaMin = 17218
|
109
|
+
suspect = no
|
110
|
+
thresholded =
|
111
|
+
timeCollected = 2012-11-16T13:40:32.362
|
112
|
+
update = 65539
|
113
|
+
|
114
|
+
1.9.3p194 :018 > ucs.show_all(statsml,'fcStats') # output omitted
|
76
115
|
|
77
116
|
== Features
|
78
117
|
|
79
118
|
1. List inventory of UCS components
|
80
119
|
2. Provision - turn up ports, create port channels, pools, service profiles
|
81
|
-
|
120
|
+
3. Retrieve stats
|
82
121
|
|
83
122
|
== ToDo
|
84
123
|
|
data/lib/ucslib/inventory.rb
CHANGED
@@ -31,6 +31,7 @@ class UCSInventory
|
|
31
31
|
xml.classId("value" => "topSystem")
|
32
32
|
xml.classId("value" => "equipmentChassis")
|
33
33
|
xml.classId("value" => "computeBlade")
|
34
|
+
xml.classId("value" => "networkElement")
|
34
35
|
xml.classId("value" => "equipmentSwitchCard")
|
35
36
|
xml.classId("value" => "equipmentIOCard")
|
36
37
|
xml.classId("value" => "equipmentFanModule")
|
@@ -161,4 +162,4 @@ class UCSInventory
|
|
161
162
|
|
162
163
|
end
|
163
164
|
|
164
|
-
end
|
165
|
+
end
|
data/lib/ucslib/manage.rb
CHANGED
@@ -25,45 +25,72 @@ class UCSManage
|
|
25
25
|
|
26
26
|
end
|
27
27
|
|
28
|
-
def associate_service_profile_template_to_server_pool(json)
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
}
|
54
|
-
}
|
29
|
+
def discover_state
|
30
|
+
|
31
|
+
#Start Build of the Multi-Class XML for interogating state
|
32
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
33
|
+
xml.configResolveClasses('cookie' => @cookie, 'inHierarchical' => 'false') {
|
34
|
+
xml.inIds{
|
35
|
+
xml.classId("value" => "macpoolPooled")
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
#End Build Multi-Class XML
|
41
|
+
|
42
|
+
ucs_multi_class_state_xml = xml_builder.to_xml.to_s
|
43
|
+
ucs_response_multi_class_state = RestClient.post(@url, ucs_multi_class_state_xml, :content_type => 'text/xml').body
|
44
|
+
|
45
|
+
#Uncomment the following to create a dump to review and debug elements
|
46
|
+
# fh = File.new("ucs_response_multiclass_state.xml", "w")
|
47
|
+
# fh.puts ucs_response_multi_class_state.inspect
|
48
|
+
# fh.close
|
49
|
+
|
50
|
+
Nokogiri::XML(ucs_response_multi_class_state)
|
51
|
+
|
55
52
|
end
|
53
|
+
|
54
|
+
|
55
|
+
def associate_service_profile_template_to_server_pool(json)
|
56
|
+
|
57
|
+
service_profile_boot_policy = JSON.parse(json)['service_profile_boot_policy']
|
58
|
+
service_profile_host_fw_policy = JSON.parse(json)['service_profile_host_fw_policy']
|
59
|
+
service_profile_mgmt_fw_policy = JSON.parse(json)['service_profile_mgmt_fw_policy']
|
60
|
+
service_profile_uuid_pool = JSON.parse(json)['service_profile_uuid_pool']
|
61
|
+
service_profile_template_to_bind = JSON.parse(json)['service_profile_template_to_bind']
|
62
|
+
service_profile_server_pool = JSON.parse(json)['service_profile_server_pool']
|
63
|
+
org = JSON.parse(json)['org']
|
64
|
+
|
65
|
+
|
66
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
67
|
+
xml.configConfMos('cookie' => "#{@cookie}", 'inHierarchical' => 'true'){
|
68
|
+
xml.inConfigs{
|
69
|
+
xml.pair('key' => "org-root/org-#{org}/ls-#{service_profile_template_to_bind}"){
|
70
|
+
xml.lsServer('agentPolicyName' => '', 'biosProfileName' => '', 'bootPolicyName' => "#{service_profile_boot_policy}",
|
71
|
+
'descr' => '', 'dn' => "org-root/org-#{org}/ls-#{service_profile_template_to_bind}",
|
72
|
+
'dynamicConPolicyName' => '', 'extIPState' => 'none', 'hostFwPolicyName' => "#{service_profile_host_fw_policy}",
|
73
|
+
'identPoolName' => "#{service_profile_uuid_pool}", 'localDiskPolicyName' => 'default', 'maintPolicyName' => 'default',
|
74
|
+
'mgmtAccessPolicyName' => '', 'mgmtFwPolicyName' => "#{service_profile_mgmt_fw_policy}", 'powerPolicyName' => 'default',
|
75
|
+
'scrubPolicyName' => '', 'solPolicyName' => 'default', 'srcTemplName' => '',
|
76
|
+
'statsPolicyName' => 'default', 'status' => 'created,modified', 'usrLbl' => '', 'uuid' => '0', 'vconProfileName' => ''){
|
77
|
+
xml.lsRequirement('name' => "#{service_profile_server_pool}", 'qualifier' => '', 'restrictMigration' => 'no', 'rn' => 'pn-req')
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
end
|
56
83
|
|
57
|
-
|
84
|
+
#Create XML
|
58
85
|
|
59
|
-
|
86
|
+
associate_service_profile_template_to_server_pool_xml = xml_builder.to_xml.to_s
|
60
87
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
88
|
+
#Post
|
89
|
+
begin
|
90
|
+
RestClient.post(@url, associate_service_profile_template_to_server_pool_xml, :content_type => 'text/xml').body
|
91
|
+
rescue Exception => e
|
92
|
+
raise "Error #{e}"
|
93
|
+
end
|
67
94
|
|
68
95
|
end
|
69
96
|
end
|
data/lib/ucslib/stats.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
class UCSStats
|
2
|
+
def fetch(tokenjson)
|
3
|
+
cookie = "#{JSON.parse(tokenjson)['cookie']}"
|
4
|
+
ip = "#{JSON.parse(tokenjson)['ip']}"
|
5
|
+
url = "https://#{ip}/nuova"
|
6
|
+
|
7
|
+
#Start Build the Multi-Class XML
|
8
|
+
|
9
|
+
# Note, the list of stats was gathered by changing hierarchical to "true" in
|
10
|
+
# inventory.rb, pointing at UCS and then searching the 10M XML for 'Stats' :)
|
11
|
+
#
|
12
|
+
# Like this:
|
13
|
+
# tr '>' '\n' < /tmp/ucs-play.xml | grep Stats | grep -v Policy | awk '{print $1}' | sort -u | grep -v / | tr -d '<' | grep -v Hist
|
14
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
15
|
+
xml.configResolveClasses('cookie' => cookie, 'inHierarchical' => 'false') {
|
16
|
+
xml.inIds{
|
17
|
+
xml.classId("value" => "adaptorEthPortStats")
|
18
|
+
xml.classId("value" => "adaptorEthPortErrStats")
|
19
|
+
xml.classId("value" => "adaptorEthPortMcastStats")
|
20
|
+
xml.classId("value" => "adaptorVnicStats")
|
21
|
+
xml.classId("value" => "computeMbPowerStats")
|
22
|
+
xml.classId("value" => "computeMbTempStats")
|
23
|
+
xml.classId("value" => "computePCIeFatalStats")
|
24
|
+
xml.classId("value" => "computePCIeFatalCompletionStats")
|
25
|
+
xml.classId("value" => "computePCIeFatalProtocolStats")
|
26
|
+
xml.classId("value" => "computePCIeFatalReceiveStats")
|
27
|
+
xml.classId("value" => "equipmentChassisStats")
|
28
|
+
xml.classId("value" => "equipmentFanStats")
|
29
|
+
xml.classId("value" => "equipmentFanModuleStats")
|
30
|
+
xml.classId("value" => "equipmentIOCardStats")
|
31
|
+
xml.classId("value" => "equipmentNetworkElementFanStats")
|
32
|
+
xml.classId("value" => "equipmentPsuStats")
|
33
|
+
xml.classId("value" => "equipmentPsuInputStats")
|
34
|
+
xml.classId("value" => "etherErrStats")
|
35
|
+
xml.classId("value" => "etherLossStats")
|
36
|
+
xml.classId("value" => "etherPauseStats")
|
37
|
+
xml.classId("value" => "etherRxStats")
|
38
|
+
xml.classId("value" => "etherTxStats")
|
39
|
+
xml.classId("value" => "fcStats")
|
40
|
+
xml.classId("value" => "fcErrStats")
|
41
|
+
xml.classId("value" => "memoryArrayEnvStats")
|
42
|
+
xml.classId("value" => "memoryErrorStats")
|
43
|
+
xml.classId("value" => "memoryUnitEnvStats")
|
44
|
+
xml.classId("value" => "processorEnvStats")
|
45
|
+
xml.classId("value" => "processorErrorStats")
|
46
|
+
xml.classId("value" => "swEnvStats")
|
47
|
+
xml.classId("value" => "swSystemStats")
|
48
|
+
}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
#End Build Multi-Class XML
|
52
|
+
|
53
|
+
ucs_multi_class_XML = xml_builder.to_xml.to_s
|
54
|
+
ucs_response_multi_class = RestClient.post(url, ucs_multi_class_XML, :content_type => 'text/xml').body
|
55
|
+
|
56
|
+
#Uncomment the following to create a dump to review and debug elements
|
57
|
+
# fh = File.new("ucs_response_multiclass.xml", "w")
|
58
|
+
# fh.puts ucs_response_multi_class.inspect
|
59
|
+
# fh.close
|
60
|
+
return Nokogiri::XML(ucs_response_multi_class)
|
61
|
+
end
|
62
|
+
|
63
|
+
def show_sample(xml,statname,all=false)
|
64
|
+
list = xml.xpath("configResolveClasses/outConfigs/#{statname}")
|
65
|
+
list = [list.first] unless all
|
66
|
+
list.each do |i|
|
67
|
+
show_attributes(i)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def show_all(xml,statname)
|
72
|
+
show_sample(xml,statname,true)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
def show_attributes(item)
|
77
|
+
print "The attributes for #{item.name} for dn=#{item.attributes['dn']} are:\n"
|
78
|
+
item.attributes.keys.each do |attr|
|
79
|
+
next if attr == 'dn'
|
80
|
+
print " #{attr} = #{item.attributes[attr]}\n"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/ucslib/version.rb
CHANGED
data/lib/ucslib.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ucslib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -116,6 +116,7 @@ files:
|
|
116
116
|
- lib/ucslib/parser.rb
|
117
117
|
- lib/ucslib/provision.rb
|
118
118
|
- lib/ucslib/session.rb
|
119
|
+
- lib/ucslib/stats.rb
|
119
120
|
- lib/ucslib/update.rb
|
120
121
|
- lib/ucslib/version.rb
|
121
122
|
- ucslib.gemspec
|