ucslib 0.1.1 → 0.1.2
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/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
|