├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── analyizer └── main.go ├── cim_instance.go ├── cim_type.go ├── client.go ├── client_cimxml.go ├── debug.go ├── exceptions.go ├── generate_id.go ├── go.mod ├── go.sum ├── main_test.go ├── params └── main.go ├── testfiles ├── ACLTest.mof ├── Bug3466280.xml ├── Bug3598613.xml ├── CIM_Min25.mof ├── EmbObjGetClass.xml ├── EmbObjGetInstNegative.xml ├── EmbObjGetInstNegative2.xml ├── EmbObjGetInstance.xml ├── EmbObjMethodRsp.xml ├── EnumClassesInput.xml ├── MethodRspWithReference.xml ├── MultiReqInput.xml ├── MultiReqResp.xml ├── NestedEmbInst.xml ├── ReturnValue.SVC.xml ├── SVCEnumQualiTypes.xml ├── SVCGetClass.xml ├── SVCMethodRsp.smpl0.xml ├── SVCMethodRsp.xml ├── ValueTypeEnumInstanceNames.xml ├── createInstance.xml ├── enumerateClasses.xml ├── enumerateClassesError.xml ├── indicationTest.mof ├── remote.mof ├── socketCat │ ├── httpHeaderAcceptApplicationStar.in │ ├── httpHeaderAcceptApplicationXml.in │ ├── httpHeaderAcceptBad.in │ ├── httpHeaderAcceptStarStar.in │ ├── httpHeaderAcceptTextStar.in │ └── httpHeaderAcceptTextXml.in ├── stringArray.mof ├── testsuite.mof ├── wqlTest.mof └── xml_input │ ├── getClassCIM_ERR_INVALID_PARAMETER1.xml │ ├── getClassCIM_ERR_INVALID_PARAMETER2.xml │ ├── getClassCIM_ERR_INVALID_PARAMETER3.xml │ ├── getClassCIM_ERR_INVALID_PARAMETER4.xml │ └── getClassCIM_ERR_INVALID_PARAMETER5.xml ├── types.go ├── types_test.go ├── url.go └── wbem_dump └── main.go /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.*~ 3 | *.xcodeproj 4 | out/ 5 | *.swp 6 | *.exe 7 | *.dll 8 | *.so 9 | *.lib 10 | *.a 11 | *.db 12 | *.zip 13 | *.rar 14 | *.7z 15 | *.pem 16 | *.lic 17 | *.tsn 18 | *.bin 19 | *.csr 20 | *.prof 21 | *.log 22 | 23 | wbem_dump/192.168.1.14/ 24 | wbem_dump/192.168.1.157/ 25 | wbem_dump/192.168.1.141/ 26 | wbem_dump/192.168.1.14_old/ 27 | wbem_dump -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: "1.10" 3 | install: 4 | - export PATH=$PATH:$HOME/gopath/bin 5 | - go get github.com/aryann/difflib 6 | - go get github.com/google/go-cmp/cmp 7 | - go get github.com/google/go-cmp/cmp/cmpopts 8 | 9 | services: 10 | 11 | before_script: 12 | 13 | script: 14 | - go test -v 15 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /analyizer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "encoding/xml" 7 | "fmt" 8 | "io/ioutil" 9 | "log" 10 | "net/http" 11 | "os" 12 | "path/filepath" 13 | 14 | "github.com/runner-mei/gowbem" 15 | ) 16 | 17 | func main() { 18 | args := os.Args 19 | if len(args) != 2 { 20 | fmt.Println(len(args)) 21 | log.Fatalln("参数不正确!\r\n", args[0], " logs目录") 22 | return 23 | } 24 | output := args[1] + "_output" 25 | 26 | files, err := filepath.Glob(filepath.Join(args[1], "*.log")) 27 | if err != nil { 28 | log.Fatalln(err) 29 | return 30 | } 31 | 32 | for _, filename := range files { 33 | bs, err := ioutil.ReadFile(filename) 34 | if err != nil { 35 | fmt.Println(err) 36 | continue 37 | } 38 | 39 | bsArray := bytes.Split(bs, []byte("HTTP/1.1 200 OK")) 40 | if len(bsArray) != 2 { 41 | fmt.Println("====================") 42 | fmt.Println(string(bs)) 43 | fmt.Println() 44 | continue 45 | } 46 | req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(bsArray[0]))) 47 | if err != nil { 48 | fmt.Println("====================", err) 49 | fmt.Println(string(bs)) 50 | fmt.Println() 51 | fmt.Println(err) 52 | continue 53 | } 54 | 55 | reqArray := bytes.Split(bsArray[0], []byte("\r\n\r\n")) 56 | if len(reqArray) < 2 { 57 | fmt.Println("====================") 58 | fmt.Println(string(bsArray[0])) 59 | fmt.Println() 60 | continue 61 | } 62 | 63 | var cimReq gowbem.CIM 64 | dec := xml.NewDecoder(bytes.NewReader(reqArray[1])) 65 | err = dec.Decode(&cimReq) 66 | if err != nil { 67 | fmt.Println("====================", err) 68 | fmt.Println(string(bsArray[0])) 69 | fmt.Println(string(reqArray[1])) 70 | fmt.Println() 71 | continue 72 | } 73 | 74 | respBytes := bs[len(bsArray[0]):] 75 | respBytes = bytes.Replace(respBytes, []byte("Transfer-Encoding: chunked\r\n"), []byte(""), -1) 76 | resp, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(respBytes)), req) 77 | if err != nil { 78 | fmt.Println("====================", err) 79 | fmt.Println(string(bs)) 80 | fmt.Println() 81 | fmt.Println(err) 82 | continue 83 | } 84 | 85 | var cim gowbem.CIM 86 | 87 | dec = xml.NewDecoder(resp.Body) 88 | err = dec.Decode(&cim) 89 | if err != nil { 90 | fmt.Println("====================", err) 91 | fmt.Println(string(bs)) 92 | fmt.Println() 93 | continue 94 | } 95 | 96 | if nil == cim.Message { 97 | continue 98 | } 99 | if nil == cim.Message.SimpleRsp { 100 | continue 101 | } 102 | if nil == cim.Message.SimpleRsp.IMethodResponse { 103 | continue 104 | } 105 | if nil != cim.Message.SimpleRsp.IMethodResponse.Error { 106 | continue 107 | } 108 | 109 | namespace := req.Header.Get("Cimobject") 110 | 111 | if "GetInstance" == cim.Message.SimpleRsp.IMethodResponse.Name { 112 | instances := cim.Message.SimpleRsp.IMethodResponse.ReturnValue.Instances 113 | 114 | for _, instance := range instances { 115 | classPath := filepath.Join(output, namespace, instance.GetClassName()) 116 | if err := os.MkdirAll(classPath, 666); err != nil && !os.IsExist(err) { 117 | log.Fatalln(err) 118 | } 119 | for _, paramValue := range cimReq.Message.SimpleReq.IMethodCall.ParamValues { 120 | if paramValue.Name == "InstanceName" { 121 | filename := filepath.Join(classPath, "instances.txt") 122 | bs := []byte(paramValue.InstanceName.String()) 123 | 124 | if old, err := ioutil.ReadFile(filename); err == nil { 125 | bs = append(bs, []byte("\r\n")...) 126 | bs = append(bs, old...) 127 | } else if !os.IsNotExist(err) { 128 | fmt.Println(err) 129 | continue 130 | } 131 | 132 | if err := ioutil.WriteFile(filename, bs, 666); err != nil { 133 | fmt.Println(err) 134 | continue 135 | } 136 | } 137 | } 138 | 139 | bs, err := xml.MarshalIndent(instance, "", " ") 140 | if err != nil { 141 | fmt.Println(err) 142 | continue 143 | } 144 | 145 | if err := ioutil.WriteFile(filepath.Join(classPath, filepath.Base(filename)+".xml"), bs, 666); err != nil { 146 | fmt.Println(err) 147 | continue 148 | } 149 | } 150 | } else if "EnumerateInstanceNames" == cim.Message.SimpleRsp.IMethodResponse.Name { 151 | 152 | var className string 153 | for _, paramValue := range cimReq.Message.SimpleReq.IMethodCall.ParamValues { 154 | if paramValue.Name == "ClassName" { 155 | className = paramValue.ClassName.Name 156 | break 157 | } 158 | } 159 | if className == "" { 160 | fmt.Println("==================== class name is empty") 161 | fmt.Println(string(bs)) 162 | fmt.Println() 163 | continue 164 | } 165 | 166 | if cim.Message.SimpleRsp.IMethodResponse.ReturnValue == nil { 167 | continue 168 | } 169 | 170 | if len(cim.Message.SimpleRsp.IMethodResponse.ReturnValue.InstanceNames) == 0 { 171 | continue 172 | } 173 | 174 | var buf bytes.Buffer 175 | for _, instanceName := range cim.Message.SimpleRsp.IMethodResponse.ReturnValue.InstanceNames { 176 | buf.WriteString(instanceName.String()) 177 | buf.WriteString("\r\n") 178 | } 179 | 180 | /// @begin 将类定义写到文件 181 | classPath := filepath.Join(output, namespace, className) 182 | if err := os.MkdirAll(classPath, 666); err != nil && !os.IsExist(err) { 183 | log.Fatalln(err) 184 | } 185 | if err := ioutil.WriteFile(filepath.Join(classPath, "instances.txt"), buf.Bytes(), 666); err != nil { 186 | log.Fatalln(err) 187 | } 188 | /// @end 189 | 190 | } 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /cim_instance.go: -------------------------------------------------------------------------------- 1 | package gowbem 2 | 3 | /** 4 | * CIMElement is an abstract base class that represents a CIM 5 | * Element as defined by the Distributed Management Task Force (DMTF) CIM Infrastructure Specification (DSP004). 9 | */ 10 | type CIMElement interface { 11 | 12 | /** 13 | * Returns a string representing the name of a CIM element instance. 14 | * 15 | * @return The name of this CIM element. 16 | */ 17 | GetName() string 18 | } 19 | 20 | /** 21 | * CIMTypedElement is an abstract class that represents a CIM 22 | * element that contains just the data type, but no value. 23 | */ 24 | type CIMTypedElement interface { 25 | CIMElement 26 | 27 | /** 28 | * Returns the CIMDataType for this CIM Element. 29 | * 30 | * @return CIMDataType of this CIM element. 31 | */ 32 | GetType() CIMType 33 | } 34 | 35 | /** 36 | * CIMValuedElement is a base class used by any element that 37 | * contains a name, type and value. 38 | */ 39 | type CIMValuedElement interface { 40 | CIMTypedElement 41 | 42 | /** 43 | * Returns the value for this CIM Element. 44 | */ 45 | GetValue() interface{} 46 | } 47 | 48 | type CIMProperty interface { 49 | CIMValuedElement 50 | 51 | /** 52 | * Returns the class in which this property was defined or overridden. 53 | * 54 | * @return Name of class where this property was defined. 55 | */ 56 | GetOriginClass() string 57 | 58 | /** 59 | * Convenience method for determining if this property is a Key. 60 | * 61 | * @return true if this property is a key. 62 | */ 63 | IsKey() bool 64 | 65 | /** 66 | * Determines if this property is Propagated. When this property is part of 67 | * a class, this value designates that the class origin value is the same as 68 | * the class name. 69 | * 70 | * @return true if this property is propagated. 71 | */ 72 | IsPropagated() bool 73 | } 74 | 75 | /** 76 | * This class represents a CIM instance as defined by the Distributed Management 77 | * Task Force (DMTF) CIM Infrastructure 78 | * Specification (DSP004). 81 | */ 82 | type CIMInstance interface { 83 | 84 | /** 85 | * Get the name of the class that instantiates this CIM instance. 86 | * 87 | * @return Name of class that instantiates this CIM instance. 88 | */ 89 | GetClassName() string 90 | 91 | /** 92 | * Retrieve an array of the properties for this instance. 93 | * 94 | * @return An array of the CIM properties for this instance. 95 | */ 96 | GetProperties() []CIMProperty 97 | 98 | /** 99 | * Get a class property by index. 100 | * 101 | * @param pIndex 102 | * The index of the class property to retrieve. 103 | * @return The CIMProperty at the specified index. 104 | * @throws ArrayIndexOutOfBoundsException 105 | */ 106 | GetPropertyByIndex(index int) CIMProperty 107 | 108 | /** 109 | * Returns the specified property. 110 | * 111 | * @param pName 112 | * The text string for the name of the property. 113 | * @return The property requested or null if the property does 114 | * not exist. 115 | */ 116 | GetPropertyByName(name string) CIMProperty 117 | 118 | /** 119 | * Returns the specified CIMProperty. 120 | * 121 | * @param pName 122 | * The string name of the property to get. 123 | * @param pOriginClass 124 | * (Optional) The string name of the class in which the property 125 | * was defined. 126 | * @return null if the property does not exist, otherwise 127 | * returns the CIM property. 128 | */ 129 | GetPropertyByNameAndOrigin(name, originClass string) CIMProperty 130 | 131 | /** 132 | * Get the number of properties defined in this CIMInstance. 133 | * 134 | * @return The number of properties defined in the CIMInstance. 135 | */ 136 | GetPropertyCount() int 137 | } 138 | 139 | type CIMParamValue interface { 140 | GetName() string 141 | GetParamType() string 142 | GetValue() Valuer 143 | } 144 | 145 | type Valuer interface { 146 | String() string 147 | } 148 | 149 | type CIMKeyBinding interface { 150 | GetName() string 151 | GetType() CIMType 152 | GetValue() interface{} 153 | } 154 | 155 | type CIMKeyBindings interface { 156 | Len() int 157 | Get(idx int) CIMKeyBinding 158 | String() string 159 | } 160 | 161 | type CIMInstanceName interface { 162 | GetClassName() string 163 | GetKeyBindings() CIMKeyBindings 164 | String() string 165 | } 166 | 167 | /** 168 | * This class represents the CIM Object Path as defined by the Distributed 169 | * Management Task Force (DMTF) CIM 170 | * Infrastructure Specification (DSP004). In order to uniquely identify a given object, a CIM object path 173 | * includes the host, namespace, object name and keys (if the object is an 174 | * instance).
175 | *
176 | * For example, the object path:
177 | *
178 | * 179 | * http://myserver/root/cimv2:My_ComputerSystem.Name=mycomputer, 180 | * CreationClassName=My_ComputerSystem 181 | *
182 | *
183 | * has two parts:
184 | *
185 | * 202 | */ 203 | type CIMObjectPath interface { 204 | 205 | /** 206 | * Gets the host. 207 | */ 208 | GetHost() string 209 | 210 | /** 211 | * Gets a key property by name. 212 | * 213 | * @param pName 214 | * The name of the key property to retrieve. 215 | * @return The CIMProperty with the given name, or 216 | * null if it is not found. 217 | */ 218 | GetKey(name string) CIMValuedElement 219 | 220 | /** 221 | * Gets all key properties. 222 | * 223 | * @return The container of key properties. 224 | */ 225 | GetKeys() map[string]CIMValuedElement 226 | 227 | /** 228 | * Gets the namespace. 229 | * 230 | * @return The name of the namespace. 231 | */ 232 | GetNamespace() string 233 | 234 | /** 235 | * Gets the object name. Depending on the type of CIM element referenced, 236 | * this may be either a class name or a qualifier type name. 237 | * 238 | * @return The name of this CIM element. 239 | */ 240 | GetObjectName() string 241 | 242 | /** 243 | * Gets the the port on the host to which the connection was established. 244 | * 245 | * @return The port on the host. 246 | */ 247 | GetPort() string 248 | 249 | /** 250 | * Get the connection scheme. 251 | * 252 | * @return The connection scheme (e.g. http, https,...) 253 | */ 254 | GetScheme() string 255 | } 256 | 257 | type CIMInstanceWithName interface { 258 | GetName() CIMInstanceName 259 | GetInstance() CIMInstance 260 | } 261 | -------------------------------------------------------------------------------- /cim_type.go: -------------------------------------------------------------------------------- 1 | package gowbem 2 | 3 | type CIMTypeCode int 4 | 5 | const ( 6 | INVALID CIMTypeCode = iota 7 | BOOLEAN 8 | STRING 9 | CHAR16 10 | UINT8 11 | SINT8 12 | UINT16 13 | SINT16 14 | UINT32 15 | SINT32 16 | UINT64 17 | SINT64 18 | DATETIME 19 | REAL32 20 | REAL64 21 | NUMERIC 22 | REFERENCE 23 | ) 24 | 25 | const ( 26 | NON_ARRAY = 0 27 | UNBOUNDED_ARRAY = -1 28 | ) 29 | 30 | var ( 31 | INVALID_TYPE = CIMType{typeCode: INVALID} 32 | 33 | types = map[string]CIMType{ 34 | "": CIMType{typeCode: INVALID}, 35 | "boolean": CIMType{typeCode: BOOLEAN}, 36 | "string": CIMType{typeCode: STRING}, 37 | "char16": CIMType{typeCode: CHAR16}, 38 | "uint8": CIMType{typeCode: UINT8}, 39 | "sint8": CIMType{typeCode: SINT8}, 40 | "uint16": CIMType{typeCode: UINT16}, 41 | "sint16": CIMType{typeCode: SINT16}, 42 | "uint32": CIMType{typeCode: UINT32}, 43 | "sint32": CIMType{typeCode: SINT32}, 44 | "uint64": CIMType{typeCode: UINT64}, 45 | "sint64": CIMType{typeCode: SINT64}, 46 | "datetime": CIMType{typeCode: DATETIME}, 47 | "real32": CIMType{typeCode: REAL32}, 48 | "real64": CIMType{typeCode: REAL64}, 49 | "numeric": CIMType{typeCode: NUMERIC}, 50 | "reference": CIMType{typeCode: REFERENCE}, 51 | } 52 | ) 53 | 54 | type CIMType struct { 55 | typeCode CIMTypeCode 56 | /** 57 | * non array if =0
58 | * unbounded if <0
59 | * bounded if >0 60 | */ 61 | arraySize int 62 | refClassName string 63 | } 64 | 65 | /** 66 | * Returns the class name of the CIM REFERENCE data type. 67 | * 68 | * @return The CIM REFERENCE class name. 69 | */ 70 | func (self *CIMType) GetClassName() string { 71 | return self.refClassName 72 | } 73 | 74 | /** 75 | * Returns the size of the maximum number of elements an array data type may 76 | * hold. 77 | * 78 | * @return The maximum size of the array data type. 79 | */ 80 | func (self *CIMType) GetSize() int { 81 | return self.arraySize 82 | } 83 | 84 | /** 85 | * Returns the data type. 86 | * 87 | * @return The data type. 88 | */ 89 | func (self *CIMType) GetType() CIMTypeCode { 90 | return self.typeCode 91 | } 92 | 93 | /** 94 | * Checks if the data type is an array type. 95 | * 96 | * @return true if the data type is an array type, 97 | * false otherwise. 98 | */ 99 | func (self *CIMType) IsArray() bool { 100 | return self.arraySize == 0 101 | } 102 | 103 | func CreateCIMType(t string) CIMType { 104 | if ct, ok := types[t]; ok { 105 | return ct 106 | } 107 | return CIMType{typeCode: INVALID} 108 | } 109 | 110 | func CreateCIMArrayType(t string, arraySize int) CIMType { 111 | if ct, ok := types[t]; ok { 112 | ct.arraySize = arraySize 113 | return ct 114 | } 115 | return CIMType{typeCode: INVALID, arraySize: arraySize} 116 | } 117 | 118 | func CreateCIMReferenceType(class string) CIMType { 119 | return CIMType{typeCode: REFERENCE, refClassName: class} 120 | } 121 | -------------------------------------------------------------------------------- /client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 VMware, Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // this code is copy from https://github.com/vmware/govmomi/blob/master/vim25/soap/client.go 17 | package gowbem 18 | 19 | import ( 20 | "bytes" 21 | "context" 22 | "crypto/tls" 23 | "encoding/json" 24 | "encoding/xml" 25 | "errors" 26 | "fmt" 27 | "io" 28 | "net/http" 29 | "net/http/cookiejar" 30 | "net/http/httputil" 31 | "net/url" 32 | "strconv" 33 | "sync/atomic" 34 | ) 35 | 36 | var ErrUnauthorized = errors.New("401 Unauthorized") 37 | 38 | type HasFault interface { 39 | Fault() error 40 | } 41 | 42 | type DecodeError struct { 43 | bytes []byte 44 | err error 45 | } 46 | 47 | func (f *DecodeError) Error() string { 48 | return f.err.Error() + ", xml as follow:\r\n" + string(f.bytes) 49 | } 50 | 51 | type FaultError struct { 52 | bytes []byte 53 | err error 54 | } 55 | 56 | func (f *FaultError) Error() string { 57 | return f.err.Error() + ", xml as follow:\r\n" + string(f.bytes) 58 | } 59 | 60 | type RoundTripper interface { 61 | RoundTrip(action string, reqBody interface{}, resBody HasFault, cached *bytes.Buffer) error 62 | } 63 | 64 | var cn uint64 // Client counter 65 | 66 | type Client struct { 67 | rn uint64 // Request counter 68 | 69 | http.Client 70 | 71 | u url.URL 72 | insecure bool 73 | contentType string 74 | 75 | cn_str string // Client counter 76 | cn uint64 // Client counter 77 | cached *bytes.Buffer 78 | } 79 | 80 | func NewClient(u *url.URL, insecure bool) *Client { 81 | c := &Client{} 82 | c.init(u, insecure) 83 | return c 84 | } 85 | 86 | func (c *Client) init(u *url.URL, insecure bool) { 87 | c.u = *u 88 | c.insecure = insecure 89 | c.cn = atomic.AddUint64(&cn, 1) 90 | c.rn = 0 91 | c.cached = bytes.NewBuffer(make([]byte, 0, 8*1024*1024)) 92 | 93 | c.cn_str = strconv.FormatUint(c.cn, 10) 94 | 95 | if c.u.Scheme == "https" { 96 | c.Client.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: c.insecure}} 97 | } 98 | 99 | c.Jar, _ = cookiejar.New(nil) 100 | //c.u.User = nil 101 | } 102 | 103 | func (c *Client) generateId() string { 104 | return c.cn_str + "-" + GenerateId() 105 | } 106 | 107 | func (c *Client) URL() url.URL { 108 | return c.u 109 | } 110 | 111 | type marshaledClient struct { 112 | Cookies []*http.Cookie 113 | URL *url.URL 114 | Insecure bool 115 | } 116 | 117 | func (c *Client) MarshalJSON() ([]byte, error) { 118 | m := marshaledClient{ 119 | Cookies: c.Jar.Cookies(&c.u), 120 | URL: &c.u, 121 | Insecure: c.insecure, 122 | } 123 | 124 | return json.Marshal(m) 125 | } 126 | 127 | func (c *Client) UnmarshalJSON(b []byte) error { 128 | var m marshaledClient 129 | 130 | err := json.Unmarshal(b, &m) 131 | if err != nil { 132 | return err 133 | } 134 | 135 | *c = *NewClient(m.URL, m.Insecure) 136 | c.Jar.SetCookies(m.URL, m.Cookies) 137 | return nil 138 | } 139 | 140 | func (c *Client) RoundTrip(ctx context.Context, action string, headers map[string]string, reqBody interface{}, resBody HasFault) error { 141 | err := c.roundTrip(ctx, action, headers, reqBody, resBody) 142 | if err != nil && atomic.LoadUint64(&c.rn) <= 1 { 143 | if c.contentType == "" { 144 | if headers == nil { 145 | headers = map[string]string{ 146 | `Content-Type`: `text/xml; charset="utf-8"`, 147 | } 148 | } else { 149 | headers[`Content-Type`] = `text/xml; charset="utf-8"` 150 | } 151 | 152 | e := c.roundTrip(ctx, action, headers, reqBody, resBody) 153 | if e == nil { 154 | c.contentType = `text/xml; charset="utf-8"` 155 | return nil 156 | } 157 | } 158 | } else if err == ErrUnauthorized { 159 | return c.roundTrip(ctx, action, headers, reqBody, resBody) 160 | } 161 | return err 162 | } 163 | 164 | func (c *Client) roundTrip(ctx context.Context, action string, headers map[string]string, reqBody interface{}, resBody HasFault) error { 165 | var httpreq *http.Request 166 | var httpres *http.Response 167 | var dumpWriter io.WriteCloser 168 | var err error 169 | 170 | num := atomic.AddUint64(&c.rn, 1) 171 | c.cached.Reset() 172 | 173 | c.cached.WriteString(xml.Header) 174 | 175 | if err = xml.NewEncoder(c.cached).Encode(reqBody); err != nil { 176 | panic(err) 177 | } 178 | rawreqbody := c.cached 179 | 180 | httpreq, err = http.NewRequest(action, c.u.String(), rawreqbody) 181 | if err != nil { 182 | panic(err) 183 | } 184 | if ctx != nil { 185 | httpreq = httpreq.WithContext(ctx) 186 | } 187 | 188 | //if pwd, ok := c.u.User.Password(); ok { 189 | // httpreq.SetBasicAuth(c.u.User.Username(), pwd) 190 | //} 191 | 192 | //httpreq.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`) 193 | if c.contentType == "" { 194 | httpreq.Header.Set(`Content-Type`, `application/xml; charset="utf-8"`) 195 | } else { 196 | httpreq.Header.Set(`Content-Type`, c.contentType) 197 | } 198 | if 0 != len(headers) { 199 | for k, v := range headers { 200 | httpreq.Header.Set(k, v) 201 | } 202 | } 203 | 204 | if DebugEnabled() { 205 | b, _ := httputil.DumpRequestOut(httpreq, false) 206 | dumpWriter = DebugNewFile(fmt.Sprintf("%d-%04d.log", c.cn, num)) 207 | defer dumpWriter.Close() 208 | dumpWriter.Write(b) 209 | dumpWriter.Write(c.cached.Bytes()) 210 | } 211 | 212 | //tstart := time.Now() 213 | httpres, err = c.Client.Do(httpreq) 214 | //tstop := time.Now() 215 | 216 | // if DebugEnabled() { 217 | // now := time.Now().Format("2006-01-02T15-04-05.999999999") 218 | // ms := tstop.Sub(tstart) / time.Millisecond 219 | // fmt.Fprintf(c.log, "%s: %4d took %6dms\n", now, num, ms) 220 | // } 221 | 222 | if err != nil { 223 | if DebugEnabled() { 224 | dumpWriter.Write([]byte("\r\n")) 225 | dumpWriter.Write([]byte(err.Error())) 226 | } 227 | 228 | return err 229 | } 230 | 231 | if httpres.StatusCode == http.StatusUnauthorized { 232 | httpres.Close = true 233 | return ErrUnauthorized 234 | } 235 | 236 | //var rawresbody io.Reader = httpres.Body 237 | defer httpres.Body.Close() 238 | 239 | if httpres.ContentLength <= 0 && (httpres.StatusCode < http.StatusOK || httpres.StatusCode >= http.StatusMultipleChoices) { 240 | 241 | if DebugEnabled() { 242 | b, _ := httputil.DumpResponse(httpres, false) 243 | dumpWriter.Write([]byte("\r\n")) 244 | dumpWriter.Write(b) 245 | dumpWriter.Write(c.cached.Bytes()) 246 | } 247 | 248 | // 修复 pg 导到一个问题, 当pg出错时返回错误响应时,没有 ContentLength, tcp 连接也不关闭。 249 | // 这时读 httpres.Body 时会导致本方法挂起。 250 | // This is Pegasus bug, pegasus will return a error response that http version is 1.0 and ContentLength is missing. 251 | // And tcp connection isn't disconnect by the pegasus server. 252 | cimError := httpres.Header.Get("CIMError") 253 | errorDetail := httpres.Header.Get("PGErrorDetail") 254 | if "" == cimError { 255 | if "" != errorDetail { 256 | return errors.New(errorDetail) 257 | } 258 | return errors.New(httpres.Status) 259 | } 260 | if "" != errorDetail { 261 | return errors.New(cimError + ": " + errorDetail) 262 | } 263 | return errors.New(cimError) 264 | } 265 | 266 | c.cached.Reset() 267 | if _, err = io.Copy(c.cached, httpres.Body); nil != err { 268 | return err 269 | } 270 | 271 | if DebugEnabled() { 272 | b, _ := httputil.DumpResponse(httpres, false) 273 | dumpWriter.Write([]byte("\r\n")) 274 | dumpWriter.Write(b) 275 | dumpWriter.Write(c.cached.Bytes()) 276 | } 277 | 278 | if 200 != httpres.StatusCode { 279 | if 0 == c.cached.Len() { 280 | return errors.New(httpres.Status) 281 | } 282 | return errors.New(httpres.Status + ":" + c.cached.String()) 283 | } 284 | 285 | dec := xml.NewDecoder(bytes.NewReader(c.cached.Bytes())) 286 | err = dec.Decode(resBody) 287 | if err != nil { 288 | return &DecodeError{bytes: c.cached.Bytes(), err: err} 289 | } 290 | 291 | if fault := resBody.Fault(); fault != nil { 292 | return &FaultError{bytes: c.cached.Bytes(), err: fault} 293 | } 294 | 295 | return nil 296 | } 297 | 298 | func StringsWith(instance CIMInstance, key string, defaultVlaue []string) []string { 299 | prop := instance.GetPropertyByName(key) 300 | if prop == nil { 301 | return defaultVlaue 302 | } 303 | value := prop.GetValue() 304 | if value == nil { 305 | return defaultVlaue 306 | } 307 | switch vv := value.(type) { 308 | case []string: 309 | return vv 310 | case []interface{}: 311 | var ss = make([]string, 0, len(vv)) 312 | for _, v := range vv { 313 | ss = append(ss, fmt.Sprint(v)) 314 | } 315 | return ss 316 | default: 317 | panic(fmt.Sprintf("[wbem] value isn't a array - %T %#v.", value, value)) 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /debug.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 VMware, Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // this code is copy from https://github.com/vmware/govmomi/blob/master/vim25/debug/debug.go 17 | package gowbem 18 | 19 | import ( 20 | "io" 21 | "os" 22 | "path/filepath" 23 | ) 24 | 25 | // Provider specified the interface types must implement to be used as a 26 | // debugging sink. Having multiple such sink implementations allows it to be 27 | // changed externally (for example when running tests). 28 | type DebugProvider interface { 29 | NewFile(s string) io.WriteCloser 30 | Flush() 31 | } 32 | 33 | var currentDebugProvider DebugProvider = nil 34 | 35 | func SetDebugProvider(p DebugProvider) { 36 | if currentDebugProvider != nil { 37 | currentDebugProvider.Flush() 38 | } 39 | currentDebugProvider = p 40 | } 41 | 42 | // Enabled returns whether debugging is enabled or not. 43 | func DebugEnabled() bool { 44 | return currentDebugProvider != nil 45 | } 46 | 47 | // NewFile dispatches to the current provider's NewFile function. 48 | func DebugNewFile(s string) io.WriteCloser { 49 | return currentDebugProvider.NewFile(s) 50 | } 51 | 52 | // Flush dispatches to the current provider's Flush function. 53 | func DebugFlush() { 54 | currentDebugProvider.Flush() 55 | } 56 | 57 | // FileProvider implements a debugging provider that creates a real file for 58 | // every call to NewFile. It maintains a list of all files that it creates, 59 | // such that it can close them when its Flush function is called. 60 | type FileDebugProvider struct { 61 | Path string 62 | 63 | // files []*os.File 64 | } 65 | 66 | func (fp *FileDebugProvider) NewFile(p string) io.WriteCloser { 67 | f, err := os.Create(filepath.Join(fp.Path, p)) 68 | if err != nil { 69 | panic(err) 70 | } 71 | 72 | // fp.files = append(fp.files, f) 73 | 74 | return f 75 | } 76 | 77 | func (fp *FileDebugProvider) Flush() { 78 | // for _, f := range fp.files { 79 | // f.Close() 80 | // } 81 | } 82 | -------------------------------------------------------------------------------- /exceptions.go: -------------------------------------------------------------------------------- 1 | package gowbem 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | type CIMStatusCode int 9 | 10 | const ( 11 | // CIMError error code constants 12 | CIM_ERR_FAILED CIMStatusCode = 1 // A general error occurred 13 | CIM_ERR_ACCESS_DENIED CIMStatusCode = 2 // Resource not available 14 | CIM_ERR_INVALID_NAMESPACE CIMStatusCode = 3 // The target namespace does not exist 15 | CIM_ERR_INVALID_PARAMETER CIMStatusCode = 4 // Parameter value(s) invalid 16 | CIM_ERR_INVALID_CLASS CIMStatusCode = 5 // The specified Class does not exist 17 | CIM_ERR_NOT_FOUND CIMStatusCode = 6 // Requested object could not be found 18 | CIM_ERR_NOT_SUPPORTED CIMStatusCode = 7 // Operation not supported 19 | CIM_ERR_CLASS_HAS_CHILDREN CIMStatusCode = 8 // Class has subclasses 20 | CIM_ERR_CLASS_HAS_INSTANCES CIMStatusCode = 9 // Class has instances 21 | CIM_ERR_INVALID_SUPERCLASS CIMStatusCode = 10 // Superclass does not exist 22 | CIM_ERR_ALREADY_EXISTS CIMStatusCode = 11 // Object already exists 23 | CIM_ERR_NO_SUCH_PROPERTY CIMStatusCode = 12 // Property does not exist 24 | CIM_ERR_TYPE_MISMATCH CIMStatusCode = 13 // Value incompatible with type 25 | CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED CIMStatusCode = 14 // Query language not supported 26 | CIM_ERR_INVALID_QUERY CIMStatusCode = 15 // Query not valid 27 | CIM_ERR_METHOD_NOT_AVAILABLE CIMStatusCode = 16 // Extrinsic method not executed 28 | CIM_ERR_METHOD_NOT_FOUND CIMStatusCode = 17 // Extrinsic method does not exist 29 | CIM_ERR_NAMESPACE_NOT_EMPTY CIMStatusCode = 20 30 | CIM_ERR_INVALID_ENUMERATION_CONTEXT CIMStatusCode = 21 31 | CIM_ERR_INVALID_OPERATION_TIMEOUT CIMStatusCode = 22 32 | CIM_ERR_PULL_HAS_BEEN_ABANDONED CIMStatusCode = 23 33 | CIM_ERR_PULL_CANNOT_BE_ABANDONED CIMStatusCode = 24 34 | CIM_ERR_FILTERED_ENUMERATION_NOT_SUPPORTED CIMStatusCode = 25 35 | CIM_ERR_CONTINUATION_ON_ERROR_NOT_SUPPORTED CIMStatusCode = 26 36 | CIM_ERR_SERVER_LIMITS_EXCEEDED CIMStatusCode = 27 37 | CIM_ERR_SERVER_IS_SHUTTING_DOWN CIMStatusCode = 28 38 | ) 39 | 40 | var ( 41 | CIMStatusCodes = []string{ 42 | "COM_ERR_OK", 43 | "CIM_ERR_FAILED", 44 | "CIM_ERR_ACCESS_DENIED", 45 | "CIM_ERR_INVALID_NAMESPACE", 46 | "CIM_ERR_INVALID_PARAMETER", 47 | "CIM_ERR_INVALID_CLASS", 48 | "CIM_ERR_NOT_FOUND", 49 | "CIM_ERR_NOT_SUPPORTED", 50 | "CIM_ERR_CLASS_HAS_CHILDREN", 51 | "CIM_ERR_CLASS_HAS_INSTANCES", 52 | "CIM_ERR_INVALID_SUPERCLASS", 53 | "CIM_ERR_ALREADY_EXISTS", 54 | "CIM_ERR_NO_SUCH_PROPERTY", 55 | "CIM_ERR_TYPE_MISMATCH", 56 | "CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED", 57 | "CIM_ERR_INVALID_QUERY", 58 | "CIM_ERR_METHOD_NOT_AVAILABLE", 59 | "CIM_ERR_METHOD_NOT_FOUND", 60 | "CIM_ERR_18", 61 | "CIM_ERR_19", 62 | "CIM_ERR_NAMESPACE_NOT_EMPTY", 63 | "CIM_ERR_INVALID_ENUMERATION_CONTEXT", 64 | "CIM_ERR_INVALID_OPERATION_TIMEOUT", 65 | "CIM_ERR_PULL_HAS_BEEN_ABANDONED", 66 | "CIM_ERR_PULL_CANNOT_BE_ABANDONED", 67 | "CIM_ERR_FILTERED_ENUMERATION_NOT_SUPPORTED", 68 | "CIM_ERR_CONTINUATION_ON_ERROR_NOT_SUPPORTED", 69 | "CIM_ERR_SERVER_LIMITS_EXCEEDED", 70 | "CIM_ERR_SERVER_IS_SHUTTING_DOWN", 71 | } 72 | ) 73 | 74 | func (code CIMStatusCode) String() string { 75 | if code > 0 && code <= 28 { 76 | return CIMStatusCodes[code] 77 | } 78 | return "COM_ERR_" + strconv.FormatInt(int64(code), 10) 79 | } 80 | 81 | type WbemError struct { 82 | code CIMStatusCode 83 | msg string 84 | } 85 | 86 | func (e *WbemError) Error() string { 87 | code_str := e.code.String() 88 | if strings.Contains(e.msg, code_str) { 89 | return e.msg 90 | } 91 | return code_str + ":" + e.msg 92 | } 93 | 94 | func WBEMException(code CIMStatusCode, msg string) error { 95 | return &WbemError{code: code, msg: msg} 96 | } 97 | 98 | func IsErrNotSupported(e error) bool { 99 | if we, ok := e.(*WbemError); ok { 100 | return we.code == CIM_ERR_NOT_SUPPORTED 101 | } 102 | if fe, ok := e.(*FaultError); ok { 103 | return IsErrNotSupported(fe.err) 104 | } 105 | return false 106 | } 107 | -------------------------------------------------------------------------------- /generate_id.go: -------------------------------------------------------------------------------- 1 | package gowbem 2 | 3 | import ( 4 | "crypto/md5" 5 | "crypto/rand" 6 | "encoding/binary" 7 | "encoding/hex" 8 | "fmt" 9 | "io" 10 | "os" 11 | "sync/atomic" 12 | "time" 13 | ) 14 | 15 | var ( 16 | // objectIdCounter is atomically incremented when generating a new ObjectId 17 | // using NewObjectId() function. It's used as a counter part of an id. 18 | objectIdCounter uint32 = 0 19 | 20 | // machineId stores machine id generated once and used in subsequent calls 21 | // to NewObjectId function. 22 | machineId = readMachineId() 23 | currentPid = os.Getpid() 24 | ) 25 | 26 | // initMachineId generates machine id and puts it into the machineId global 27 | // variable. If this function fails to get the hostname, it will cause 28 | // a runtime error. 29 | func readMachineId() []byte { 30 | var sum [3]byte 31 | id := sum[:] 32 | hostname, err1 := os.Hostname() 33 | if err1 != nil { 34 | _, err2 := io.ReadFull(rand.Reader, id) 35 | if err2 != nil { 36 | panic(fmt.Errorf("cannot get hostname: %v; %v", err1, err2)) 37 | } 38 | return id 39 | } 40 | hw := md5.New() 41 | hw.Write([]byte(hostname)) 42 | copy(id, hw.Sum(nil)) 43 | return id 44 | } 45 | 46 | // NewObjectId returns a new unique ObjectId. 47 | // This function causes a runtime error if it fails to get the hostname 48 | // of the current machine. 49 | func GenerateId() string { 50 | var b [12]byte 51 | // Timestamp, 4 bytes, big endian 52 | binary.BigEndian.PutUint32(b[:], uint32(time.Now().Unix())) 53 | // Machine, first 3 bytes of md5(hostname) 54 | b[4] = machineId[0] 55 | b[5] = machineId[1] 56 | b[6] = machineId[2] 57 | // Pid, 2 bytes, specs don't specify endianness, but we use big endian. 58 | b[7] = byte(currentPid >> 8) 59 | b[8] = byte(currentPid) 60 | // Increment, 3 bytes, big endian 61 | i := atomic.AddUint32(&objectIdCounter, 1) 62 | b[9] = byte(i >> 16) 63 | b[10] = byte(i >> 8) 64 | b[11] = byte(i) 65 | return hex.EncodeToString(b[:]) 66 | } 67 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/runner-mei/gowbem 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a 7 | github.com/google/go-cmp v0.4.0 8 | ) 9 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a h1:pv34s756C4pEXnjgPfGYgdhg/ZdajGhyOvzx8k+23nw= 2 | github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= 3 | github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= 4 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 5 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 6 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 7 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package gowbem_test 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | "fmt" 7 | "net/http" 8 | _ "net/http/pprof" 9 | "net/url" 10 | "strings" 11 | "testing" 12 | "time" 13 | 14 | . "github.com/runner-mei/gowbem" 15 | "github.com/runner-mei/gowbem/params" 16 | ) 17 | 18 | var ( 19 | schema = flag.String("scheme", "http", "") 20 | host = flag.String("host", "192.168.1.14", "") 21 | port = flag.String("port", "5988", "") 22 | path = flag.String("path", "/cimom", "") 23 | 24 | username = flag.String("username", "root", "") 25 | userpassword = flag.String("password", "", "") 26 | ) 27 | 28 | func getTestUri() *url.URL { 29 | return &url.URL{ 30 | Scheme: *schema, 31 | User: url.UserPassword(*username, *userpassword), 32 | Host: *host + ":" + *port, 33 | Path: *path, 34 | } 35 | } 36 | 37 | func TestEnumerateClassNames(t *testing.T) { 38 | if "" == *userpassword { 39 | t.Skip("please input password.") 40 | } 41 | c, e := NewClientCIMXML(getTestUri(), false) 42 | if nil != e { 43 | t.Error(e) 44 | return 45 | } 46 | 47 | timerCtx, _ := context.WithTimeout(context.Background(), 10*time.Second) 48 | names, e := c.EnumerateClassNames(timerCtx, "root/cimv2", "", false) 49 | if nil != e { 50 | t.Error(e) 51 | return 52 | } 53 | if 0 == len(names) { 54 | t.Error("class list is emtpy") 55 | return 56 | } 57 | for _, name := range names { 58 | t.Log(name) 59 | } 60 | 61 | timerCtx, _ = context.WithTimeout(context.Background(), 10*time.Second) 62 | names2, e := c.EnumerateClassNames(timerCtx, "root/cimv2", "", true) 63 | if nil != e { 64 | t.Error(e) 65 | return 66 | } 67 | if 0 == len(names2) { 68 | t.Error("class list is emtpy") 69 | return 70 | } 71 | for _, name := range names2 { 72 | t.Log(name) 73 | } 74 | 75 | if len(names) >= len(names2) { 76 | t.Error("len(names) >= len(names2)") 77 | } 78 | } 79 | 80 | func TestEnumerateInstanceNames(t *testing.T) { 81 | if "" == *userpassword { 82 | t.Skip("please input password.") 83 | } 84 | // go func() { 85 | // http.ListenAndServe(":", nil) 86 | // }() 87 | 88 | c, e := NewClientCIMXML(getTestUri(), false) 89 | if nil != e { 90 | t.Error(e) 91 | return 92 | } 93 | timerCtx, _ := context.WithTimeout(context.Background(), 10*time.Second) 94 | names, e := c.EnumerateInstanceNames(timerCtx, "root/cimv2", "Linux_UnixProcess") 95 | if nil != e { 96 | t.Error(e) 97 | return 98 | } 99 | if 0 == len(names) { 100 | t.Error("class list is emtpy") 101 | return 102 | } 103 | 104 | for idx, name := range names { 105 | if idx > 10 { 106 | break 107 | } 108 | 109 | timerCtx, _ = context.WithTimeout(context.Background(), 10*time.Second) 110 | instance1, e := c.GetInstanceByInstanceName(timerCtx, "root/cimv2", name, true, true, true, nil) 111 | if nil != e { 112 | t.Error(e) 113 | continue 114 | } 115 | t.Log(instance1) 116 | 117 | for i := 0; i < instance1.GetPropertyCount(); i++ { 118 | pr := instance1.GetPropertyByIndex(i) 119 | t.Log(pr.GetName(), "=", pr.GetValue()) 120 | } 121 | 122 | namespace, className, keyBindings, e := Parse(name.String()) 123 | if nil != e { 124 | t.Error(e) 125 | continue 126 | } 127 | if "" == namespace { 128 | namespace = "root/cimv2" 129 | } 130 | 131 | timerCtx, _ = context.WithTimeout(context.Background(), 10*time.Second) 132 | instance2, e := c.GetInstance(timerCtx, namespace, className, keyBindings, true, true, true, nil) 133 | if nil != e { 134 | t.Error(e) 135 | continue 136 | } 137 | 138 | if instance2.GetPropertyCount() != instance1.GetPropertyCount() { 139 | t.Error("property count isn't equals.") 140 | continue 141 | } 142 | } 143 | } 144 | 145 | func TestEnumerateInstances(t *testing.T) { 146 | if "" == *userpassword { 147 | t.Skip("please input password.") 148 | } 149 | // go func() { 150 | // http.ListenAndServe(":", nil) 151 | // }() 152 | 153 | c, e := NewClientCIMXML(getTestUri(), false) 154 | if nil != e { 155 | t.Error(e) 156 | return 157 | } 158 | timerCtx, _ := context.WithTimeout(context.Background(), 10*time.Second) 159 | instances, e := c.EnumerateInstances(timerCtx, "root/cimv2", "Linux_UnixProcess", false, false, false, false, nil) 160 | if nil != e { 161 | t.Error(e) 162 | return 163 | } 164 | if 0 == len(instances) { 165 | t.Error("instance list is emtpy") 166 | return 167 | } 168 | 169 | for _, instance := range instances { 170 | t.Log(instance.GetName()) 171 | for i := 0; i < instance.GetInstance().GetPropertyCount(); i++ { 172 | pr := instance.GetInstance().GetPropertyByIndex(i) 173 | t.Log(pr.GetName(), "=", pr.GetValue()) 174 | } 175 | } 176 | } 177 | 178 | func TestEnumerateInstances2(t *testing.T) { 179 | if "" == *userpassword { 180 | t.Skip("please input password.") 181 | } 182 | // go func() { 183 | // http.ListenAndServe(":", nil) 184 | // }() 185 | 186 | c, e := NewClientCIMXML(getTestUri(), false) 187 | if nil != e { 188 | t.Error(e) 189 | return 190 | } 191 | timerCtx, _ := context.WithTimeout(context.Background(), 10*time.Second) 192 | instances, e := c.EnumerateInstances(timerCtx, "root/cimv2", "CIM_Processor", false, false, false, false, nil) 193 | if nil != e { 194 | t.Error(e) 195 | return 196 | } 197 | if 0 == len(instances) { 198 | t.Error("instance list is emtpy") 199 | return 200 | } 201 | 202 | for _, instance := range instances { 203 | t.Log(instance.GetName()) 204 | for i := 0; i < instance.GetInstance().GetPropertyCount(); i++ { 205 | pr := instance.GetInstance().GetPropertyByIndex(i) 206 | t.Log(pr.GetName(), "=", pr.GetValue()) 207 | } 208 | 209 | //instanceName := instance 210 | //instanceName.GetKeyBindings().Get(0).GetValue() 211 | 212 | timerCtx, _ = context.WithTimeout(context.Background(), 10*time.Second) 213 | instanceWithNames, e := c.AssociatorInstances(timerCtx, "root/cimv2", instance.GetName(), "", "", "", "", false, nil) 214 | if nil != e { 215 | //t.Error(e) 216 | fmt.Println(e) 217 | continue 218 | } 219 | if 0 == len(instanceWithNames) { 220 | continue 221 | } 222 | 223 | for _, instance := range instanceWithNames { 224 | //t.Log(instance.GetName()) 225 | for i := 0; i < instance.GetInstance().GetPropertyCount(); i++ { 226 | pr := instance.GetInstance().GetPropertyByIndex(i) 227 | t.Log("\t", pr.GetName(), "=", pr.GetValue()) 228 | } 229 | } 230 | } 231 | } 232 | 233 | func TestGetClass(t *testing.T) { 234 | if "" == *userpassword { 235 | t.Skip("please input password.") 236 | } 237 | // go func() { 238 | // http.ListenAndServe(":", nil) 239 | // }() 240 | 241 | c, e := NewClientCIMXML(getTestUri(), false) 242 | if nil != e { 243 | t.Error(e) 244 | return 245 | } 246 | timerCtx, _ := context.WithTimeout(context.Background(), 10*time.Second) 247 | class, e := c.GetClass(timerCtx, "root/cimv2", "Linux_UnixProcess", true, true, true, nil) 248 | if nil != e { 249 | t.Error(e) 250 | return 251 | } 252 | if 0 == len(class) { 253 | t.Error("class is emtpy") 254 | return 255 | } 256 | 257 | t.Log(class) 258 | } 259 | 260 | func TestEnumerateClasses(t *testing.T) { 261 | if "" == *userpassword { 262 | t.Skip("please input password.") 263 | } 264 | // go func() { 265 | // http.ListenAndServe(":", nil) 266 | // }() 267 | 268 | c, e := NewClientCIMXML(getTestUri(), false) 269 | if nil != e { 270 | t.Error(e) 271 | return 272 | } 273 | 274 | timerCtx, _ := context.WithTimeout(context.Background(), 10*time.Second) 275 | classes, e := c.EnumerateClasses(timerCtx, "root/cimv2", "CIM_UnixProcess", true, true, true, true) 276 | if nil != e { 277 | t.Error(e) 278 | return 279 | } 280 | if 0 == len(classes) { 281 | t.Error("classes is emtpy") 282 | return 283 | } 284 | 285 | t.Log(classes) 286 | } 287 | 288 | func TestAssociatorInstances(t *testing.T) { 289 | t.Skip("timeout.") 290 | 291 | if "" == *userpassword { 292 | t.Skip("please input password.") 293 | } 294 | go func() { 295 | http.ListenAndServe(":", nil) 296 | }() 297 | 298 | c, e := NewClientCIMXML(getTestUri(), false) 299 | if nil != e { 300 | t.Error(e) 301 | return 302 | } 303 | 304 | timerCtx, _ := context.WithTimeout(context.Background(), 10*time.Second) 305 | names, e := c.EnumerateClassNames(timerCtx, "root/cimv2", "", true) 306 | if nil != e { 307 | t.Error(e) 308 | return 309 | } 310 | if 0 == len(names) { 311 | t.Error("class list is emtpy") 312 | return 313 | } 314 | fmt.Println(len(names)) 315 | for idx, name := range names { 316 | if "Linux_SysfsAttribute" == name { 317 | continue 318 | } 319 | fmt.Println(idx, "========", name) 320 | 321 | timerCtx, _ = context.WithTimeout(context.Background(), 10*time.Second) 322 | instances, e := c.EnumerateInstanceNames(timerCtx, "root/cimv2", name) //, false, false, false, false, nil) 323 | if nil != e { 324 | //t.Error(e) 325 | //return 326 | continue 327 | } 328 | if 0 == len(instances) { 329 | //t.Error("instance list is emtpy") 330 | continue 331 | } 332 | 333 | for _, instance := range instances { 334 | 335 | if strings.Contains(instance.String(), "Linux_SysfsAttribute") { 336 | continue 337 | } 338 | 339 | if strings.Contains(instance.String(), "Linux_SysfsBusDevice") { 340 | continue 341 | } 342 | 343 | if strings.Contains(instance.String(), "Linux_UnixProcess") { 344 | continue 345 | } 346 | 347 | if strings.Contains(instance.String(), "PG_UnixProcess") { 348 | continue 349 | } 350 | 351 | fmt.Println(instance) 352 | 353 | if 0 == len(instances) { 354 | //t.Error("instance list is emtpy") 355 | continue 356 | } 357 | 358 | for _, instance := range instances { 359 | fmt.Println("==========", instance) 360 | //instanceName := instance 361 | //instanceName.GetKeyBindings().Get(0).GetValue() 362 | 363 | timerCtx, _ = context.WithTimeout(context.Background(), 10*time.Second) 364 | instanceWithNames, e := c.AssociatorInstances(timerCtx, "root/cimv2", instance, "", "", "", "", false, nil) 365 | if nil != e { 366 | //t.Error(e) 367 | fmt.Println(e) 368 | continue 369 | } 370 | if 0 == len(instanceWithNames) { 371 | //t.Error("instance list is emtpy") 372 | continue 373 | } 374 | 375 | for _, instance := range instanceWithNames { 376 | //t.Log(instance.GetName()) 377 | for i := 0; i < instance.GetInstance().GetPropertyCount(); i++ { 378 | pr := instance.GetInstance().GetPropertyByIndex(i) 379 | t.Log(pr.GetName(), "=", pr.GetValue()) 380 | } 381 | } 382 | 383 | } 384 | } 385 | } 386 | 387 | } 388 | 389 | // func TestAssociatorClasses(t *testing.T) { 390 | // c, e := NewClientCIMXML(getTestUri(), false) 391 | // if nil != e { 392 | // t.Error(e) 393 | // return 394 | // } 395 | 396 | // // classes, e := c.EnumerateClasses("root/cimv2", "Linux_UnixProcess", true, true, true, true) 397 | // // if nil != e { 398 | // // t.Error(e) 399 | // // return 400 | // // } 401 | // // has_ok := false 402 | // // for _, cls := range classes { 403 | // // var clsInstance CimClassInnerXml 404 | // // if e := xml.Unmarshal([]byte(cls), &clsInstance); nil != e { 405 | // // t.Log(e) 406 | // // continue 407 | // // } 408 | 409 | // fmt.Println(clsInstance.Name) 410 | // assoc_classes, e := c.AssociatorClasses("root/cimv2", "Linux_UnixProcess", "", "", "", "", true, true, nil) 411 | // if nil != e { 412 | // t.Log(e) 413 | // return 414 | // } 415 | // if 0 == len(assoc_classes) { 416 | // t.Log("classes is emtpy") 417 | // return 418 | // } 419 | // 420 | // //has_ok = true 421 | // t.Log(assoc_classes) 422 | // fmt.Println(assoc_classes) 423 | // //} 424 | // // if !has_ok { 425 | // // t.Error("failed") 426 | // // } 427 | // } 428 | 429 | // func TestReferenceClasses(t *testing.T) { 430 | // c, e := NewClientCIMXML(getTestUri(), false) 431 | // if nil != e { 432 | // t.Error(e) 433 | // return 434 | // } 435 | 436 | // classes, e := c.EnumerateClasses("root/cimv2", "", true, true, true, true) 437 | // if nil != e { 438 | // t.Error(e) 439 | // return 440 | // } 441 | // has_ok := false 442 | // for _, cls := range classes { 443 | // var clsInstance CimClassInnerXml 444 | // if e := xml.Unmarshal([]byte(cls), &clsInstance); nil != e { 445 | // t.Log(e) 446 | // continue 447 | // } 448 | 449 | // fmt.Println(clsInstance.Name) 450 | // assoc_classes, e := c.ReferenceClasses("root/cimv2", clsInstance.Name, "", "", true, true, nil) 451 | // if nil != e { 452 | // t.Log(e) 453 | // continue 454 | // } 455 | // if 0 == len(assoc_classes) { 456 | // t.Log("classes is emtpy") 457 | // continue 458 | // } 459 | 460 | // has_ok = true 461 | // t.Log(assoc_classes) 462 | // fmt.Println(assoc_classes) 463 | // } 464 | // if !has_ok { 465 | // t.Error("failed") 466 | // } 467 | // } 468 | 469 | // func TestReferenceNames(t *testing.T) { 470 | // c, e := NewClientCIMXML(getTestUri(), false) 471 | // if nil != e { 472 | // t.Error(e) 473 | // return 474 | // } 475 | // classes, e := c.EnumerateClasses("root/cimv2", "", true, true, true, true) 476 | // if nil != e { 477 | // t.Error(e) 478 | // return 479 | // } 480 | 481 | // for _, cls := range classes { 482 | // var clsInstance CimClassInnerXml 483 | // if e := xml.Unmarshal([]byte(cls), &clsInstance); nil != e { 484 | // t.Log(e) 485 | // continue 486 | // } 487 | 488 | // fmt.Println(clsInstance.Name) 489 | 490 | // instances, e := c.EnumerateInstances("root/cimv2", clsInstance.Name, true, true, true, true, nil) 491 | // if nil != e { 492 | // t.Error(e) 493 | // continue 494 | // } 495 | // has_ok := false 496 | // for _, instance := range instances { 497 | // fmt.Println(instance.GetName().String()) 498 | // names, e := c.ReferenceNames("root/cimv2", instance.GetName(), "", "") 499 | // if nil != e { 500 | // t.Log(e) 501 | // continue 502 | // } 503 | // if 0 == len(names) { 504 | // t.Log("classes is emtpy") 505 | // continue 506 | // } 507 | 508 | // has_ok = true 509 | // t.Log(names) 510 | // fmt.Println(names) 511 | // } 512 | // if !has_ok { 513 | // t.Error("failed") 514 | // } 515 | // } 516 | // } 517 | 518 | func TestInvokeMethod(t *testing.T) { 519 | if "" == *userpassword { 520 | t.Skip("please input password.") 521 | } 522 | c, e := NewClientCIMXML(getTestUri(), false) 523 | if nil != e { 524 | t.Error(e) 525 | return 526 | } 527 | 528 | instanceName, e := ParseInstanceName(`PG_ConfigSetting.PropertyName="hostname"`) 529 | if nil != e { 530 | t.Error(e) 531 | return 532 | } 533 | 534 | timerCtx, _ := context.WithTimeout(context.Background(), 10*time.Second) 535 | value, outParams, e := c.InvokeMethod(timerCtx, "root/PG_Internal", instanceName, "UpdatePropertyValue", 536 | []CIMParamValue{params.Value("PropertyValue", "test"), params.Value("SetPlannedValue", "true")}) 537 | if nil != e { 538 | t.Error(e) 539 | return 540 | } 541 | if 0 != len(outParams) { 542 | for _, param := range outParams { 543 | t.Log(param) 544 | } 545 | } 546 | 547 | if strings.ToLower(fmt.Sprint(value)) != "true" { 548 | t.Error("except is true got ", value) 549 | } 550 | 551 | timerCtx, _ = context.WithTimeout(context.Background(), 10*time.Second) 552 | instanceValue, e := c.GetInstanceByInstanceName(timerCtx, "root/PG_Internal", instanceName, false, false, false, nil) 553 | if nil != e { 554 | t.Error(e) 555 | return 556 | } 557 | if instanceValue == nil { 558 | t.Error("instanceValue is nil") 559 | return 560 | } 561 | 562 | pvalue := instanceValue.GetPropertyByName("PlannedValue").GetValue() 563 | if fmt.Sprint(pvalue) != "test" { 564 | t.Error("except is test got ", pvalue) 565 | } 566 | } 567 | -------------------------------------------------------------------------------- /params/main.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/runner-mei/gowbem" 7 | ) 8 | 9 | func Value(name, value string) gowbem.CIMParamValue { 10 | return &gowbem.CimParamValue{ 11 | Name: name, 12 | Value: &gowbem.CimValue{Value: value}, 13 | } 14 | } 15 | 16 | func ValueArray(name string, value []interface{}) gowbem.CIMParamValue { 17 | values := make([]gowbem.CimValueOrNull, 0, len(value)) 18 | for idx := range value { 19 | if value[idx] == nil { 20 | values = append(values, gowbem.CimValueOrNull{Null: &gowbem.CimValueNull{}}) 21 | } else { 22 | values = append(values, gowbem.CimValueOrNull{Value: &gowbem.CimValue{Value: fmt.Sprint(value)}}) 23 | } 24 | } 25 | return &gowbem.CimParamValue{ 26 | Name: name, 27 | ValueArray: &gowbem.CimValueArray{Values: values}, 28 | } 29 | } 30 | 31 | func ClassName(name, className string) gowbem.CIMParamValue { 32 | return &gowbem.CimParamValue{ 33 | Name: name, 34 | ClassName: &gowbem.CimClassName{Name: className}, 35 | } 36 | } 37 | 38 | func InstanceName(name string, insName interface{}) gowbem.CIMParamValue { 39 | switch v := insName.(type) { 40 | case string: 41 | instanceName, e := gowbem.ParseInstanceName(v) 42 | if e != nil { 43 | panic(e) 44 | } 45 | return &gowbem.CimParamValue{ 46 | Name: name, 47 | InstanceName: instanceName, 48 | } 49 | 50 | case *gowbem.CimInstanceName: 51 | return &gowbem.CimParamValue{ 52 | Name: name, 53 | InstanceName: v, 54 | } 55 | 56 | case gowbem.CimInstanceName: 57 | return &gowbem.CimParamValue{ 58 | Name: name, 59 | InstanceName: &v, 60 | } 61 | 62 | default: 63 | panic(fmt.Errorf("unsupport type '%T' - %#v", insName, insName)) 64 | } 65 | } 66 | 67 | func Instance(name string, instance gowbem.CIMInstance) gowbem.CIMParamValue { 68 | return &gowbem.CimParamValue{ 69 | Name: name, 70 | Instance: instance.(*gowbem.CimInstance), 71 | } 72 | } 73 | 74 | func InstanceWithName(name string, instance gowbem.CIMInstanceWithName) gowbem.CIMParamValue { 75 | return &gowbem.CimParamValue{ 76 | Name: name, 77 | ValueNamedInstance: instance.(*gowbem.CimValueNamedInstance), 78 | } 79 | } 80 | 81 | func LocalClassPathReference(name, namespaceName, className string) gowbem.CIMParamValue { 82 | names := gowbem.SplitNamespaces(namespaceName) 83 | namespaces := make([]gowbem.CimNamespace, len(names)) 84 | for idx, name := range names { 85 | namespaces[idx].Name = name 86 | } 87 | 88 | return &gowbem.CimParamValue{ 89 | Name: name, 90 | ValueReference: &gowbem.CimValueReference{ 91 | LocalClassPath: &gowbem.CimLocalClassPath{ 92 | NamespacePath: gowbem.CimLocalNamespacePath{Namespaces: namespaces}, 93 | ClassName: gowbem.CimClassName{Name: className}, 94 | }, 95 | }, 96 | } 97 | } 98 | 99 | func ClassNameReference(name, className string) gowbem.CIMParamValue { 100 | return &gowbem.CimParamValue{ 101 | Name: name, 102 | ValueReference: &gowbem.CimValueReference{ 103 | ClassName: &gowbem.CimClassName{Name: className}, 104 | }, 105 | } 106 | } 107 | 108 | func LocalInstancePathReference(name, namespaceName string, insName interface{}) gowbem.CIMParamValue { 109 | names := gowbem.SplitNamespaces(namespaceName) 110 | namespaces := make([]gowbem.CimNamespace, len(names)) 111 | for idx, name := range names { 112 | namespaces[idx].Name = name 113 | } 114 | 115 | switch v := insName.(type) { 116 | case string: 117 | instanceName, e := gowbem.ParseInstanceName(v) 118 | if e != nil { 119 | panic(e) 120 | } 121 | return &gowbem.CimParamValue{ 122 | Name: name, 123 | ValueReference: &gowbem.CimValueReference{ 124 | LocalInstancePath: &gowbem.CimLocalInstancePath{ 125 | LocalNamespacePath: gowbem.CimLocalNamespacePath{Namespaces: namespaces}, 126 | InstanceName: *instanceName, 127 | }, 128 | }, 129 | } 130 | 131 | case *gowbem.CimInstanceName: 132 | return &gowbem.CimParamValue{ 133 | Name: name, 134 | ValueReference: &gowbem.CimValueReference{ 135 | LocalInstancePath: &gowbem.CimLocalInstancePath{ 136 | LocalNamespacePath: gowbem.CimLocalNamespacePath{Namespaces: namespaces}, 137 | InstanceName: *v, 138 | }, 139 | }, 140 | } 141 | 142 | case gowbem.CimInstanceName: 143 | return &gowbem.CimParamValue{ 144 | Name: name, 145 | ValueReference: &gowbem.CimValueReference{ 146 | LocalInstancePath: &gowbem.CimLocalInstancePath{ 147 | LocalNamespacePath: gowbem.CimLocalNamespacePath{Namespaces: namespaces}, 148 | InstanceName: v, 149 | }, 150 | }, 151 | } 152 | 153 | default: 154 | panic(fmt.Errorf("unsupport type '%T' - %#v", insName, insName)) 155 | } 156 | } 157 | 158 | func InstanceNameReference(name string, insName interface{}) gowbem.CIMParamValue { 159 | switch v := insName.(type) { 160 | case string: 161 | instanceName, e := gowbem.ParseInstanceName(v) 162 | if e != nil { 163 | panic(e) 164 | } 165 | return &gowbem.CimParamValue{ 166 | Name: name, 167 | ValueReference: &gowbem.CimValueReference{ 168 | InstanceName: instanceName, 169 | }, 170 | } 171 | 172 | case *gowbem.CimInstanceName: 173 | return &gowbem.CimParamValue{ 174 | Name: name, 175 | ValueReference: &gowbem.CimValueReference{ 176 | InstanceName: v, 177 | }, 178 | } 179 | 180 | case gowbem.CimInstanceName: 181 | return &gowbem.CimParamValue{ 182 | Name: name, 183 | ValueReference: &gowbem.CimValueReference{ 184 | InstanceName: &v, 185 | }, 186 | } 187 | 188 | default: 189 | panic(fmt.Errorf("unsupport type '%T' - %#v", insName, insName)) 190 | } 191 | } 192 | 193 | // type CimValueReference struct { 194 | // XMLName xml.Name `xml:"VALUE.REFERENCE"` 195 | // ClassPath *CimClassPath `xml:"CLASSPATH,omitempty"` 196 | // LocalClassPath *CimLocalClassPath `xml:"LOCALCLASSPATH,omitempty"` 197 | // ClassName *CimClassName `xml:"CLASSNAME,omitempty"` 198 | // InstancePath *CimInstancePath `xml:"INSTANCEPATH,omitempty"` 199 | // LocalInstancePath *CimLocalInstancePath `xml:"LOCALINSTANCEPATH,omitempty"` 200 | // InstanceName *CimInstanceName `xml:"INSTANCENAME,omitempty"` 201 | // } 202 | -------------------------------------------------------------------------------- /testfiles/ACLTest.mof: -------------------------------------------------------------------------------- 1 | class EXP_BionicComputerSystem:CIM_ComputerSystem 2 | { 3 | boolean OptionalArg; 4 | }; 5 | 6 | 7 | INSTANCE OF EXP_BionicComputerSystem 8 | { 9 | CreationClassName="EXP_BionicComputerSystem"; 10 | Name="SixMillion"; 11 | }; 12 | 13 | INSTANCE OF EXP_BionicComputerSystem 14 | { 15 | CreationClassName="EXP_BionicComputerSystem"; 16 | Name="SevenMillion"; 17 | }; 18 | 19 | INSTANCE OF CIM_SystemComponent 20 | { 21 | GroupComponent = "EXP_BionicComputerSystem.CreationClassName=\"EXP_BionicComputerSystem\",Name=\"SevenMillion\""; 22 | PartComponent = "EXP_BionicComputerSystem.CreationClassName=\"EXP_BionicComputerSystem\",Name=\"SixMillion\""; 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /testfiles/Bug3598613.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 169.254.95.120 1348544936846 11 | 12 | 13 | 1348544937 14 | 15 | 16 | 2 17 | 18 | 19 | 20 | 21 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 169.254.95.120 1348544936846 22 | 23 | 24 | 1348544937 25 | 26 | 27 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 169.254.95.120 1348544936846 28 | 29 | 30 | root 31 | 32 | 33 | /etc/opt/ibm/icc/truststore/3fb40a25.0 34 | 35 | 36 | 2 37 | 38 | 39 | 20120925034857.000000+000 40 | 41 | 42 | 20170924034857.000000+000 43 | 44 | 45 | 2 46 | 47 | 48 | 49 | 50 | 51 | 52 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 10.9.61.11 1352162758531 53 | 54 | 55 | 1352162760 56 | 57 | 58 | 2 59 | 60 | 61 | 62 | 63 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 10.9.61.11 1352162758531 64 | 65 | 66 | 1352162760 67 | 68 | 69 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 10.9.61.11 1352162758531 70 | 71 | 72 | root 73 | 74 | 75 | /etc/opt/ibm/icc/truststore/adcfb619.0 76 | 77 | 78 | 2 79 | 80 | 81 | 20121106004600.000000+000 82 | 83 | 84 | 20171105004600.000000+000 85 | 86 | 87 | 2 88 | 89 | 90 | 91 | 92 | 93 | 94 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 9.12.201.236 1349460470283 95 | 96 | 97 | 1349460472 98 | 99 | 100 | 2 101 | 102 | 103 | 104 | 105 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 9.12.201.236 1349460470283 106 | 107 | 108 | 1349460472 109 | 110 | 111 | /C=US/ST=NC/L=RTP/O=Director Development/OU=IBM Corporation/CN=IBM Director on 9.12.201.236 1349460470283 112 | 113 | 114 | root 115 | 116 | 117 | /etc/opt/ibm/icc/truststore/ff57b4bc.0 118 | 119 | 120 | 2 121 | 122 | 123 | 20121005180752.000000+000 124 | 125 | 126 | 20171004180752.000000+000 127 | 128 | 129 | 2 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /testfiles/CIM_Min25.mof: -------------------------------------------------------------------------------- 1 | // This contains a small subset of the core, so we can run the tests faster 2 | Qualifier Abstract : boolean = false, Scope(class, association, 3 | indication), Flavor(DisableOverride, Restricted); 4 | Qualifier Association : boolean = false, Scope(class, association), 5 | Flavor(DisableOverride); 6 | Qualifier Key : boolean = false, Scope(property, reference), 7 | Flavor(DisableOverride); 8 | Qualifier Override : string = null, Scope(property, method, 9 | reference); 10 | Qualifier Description : string = null, Scope(any), 11 | Flavor(Translatable); 12 | Qualifier Expensive : boolean = false, 13 | Scope(property, reference, method, class, association); 14 | Qualifier In : boolean = true, Scope(parameter); 15 | Qualifier Provider : string = null, Scope(any); 16 | Qualifier MaxLen : uint32 = null, Scope(property, method, 17 | parameter); 18 | Qualifier MappingStrings : string[], 19 | Scope(class, property, association, indication, reference); 20 | Qualifier ValueMap : string[], Scope(property, method, parameter); 21 | Qualifier ArrayType : string = "Bag", Scope(property, parameter); 22 | Qualifier ModelCorrespondence : string[], Scope(property); 23 | Qualifier Values : string[], Scope(property, method, parameter), 24 | Flavor(Translatable); 25 | Qualifier Aggregation : boolean = false, Scope(association), 26 | Flavor(DisableOverride); 27 | Qualifier Aggregate: boolean = false, Scope (reference), 28 | Flavor(DisableOverride); 29 | Qualifier Out : boolean = false, Scope(parameter), 30 | Flavor(DisableOverride); 31 | Qualifier Required : boolean = false, 32 | Scope(property, reference, parameter), 33 | Flavor(DisableOverride); 34 | 35 | 36 | 37 | 38 | // ================================================================== 39 | // ManagedElement 40 | // ================================================================== 41 | [Abstract, Description ( 42 | "ManagedElement is an abstract class that provides a common " 43 | "superclass (or top of the inheritance tree) for the " 44 | "non-association classes in the CIM Schema.")] 45 | class CIM_ManagedElement 46 | { 47 | [MaxLen (64), Description ( 48 | "The Caption property is a short textual description (one-" 49 | "line string) of the object.") ] 50 | string Caption; 51 | [Description ( 52 | "The Description property provides a textual description of " 53 | "the object.") ] 54 | string Description; 55 | }; 56 | 57 | // ================================================================== 58 | // Collection 59 | // ================================================================== 60 | [Abstract, Description ( 61 | "Collection is an abstract class that provides a common" 62 | "superclass for data elements that represent collections of " 63 | "ManagedElements and its subclasses.")] 64 | class CIM_Collection : CIM_ManagedElement 65 | { 66 | }; 67 | 68 | // ================================================================== 69 | // ManagedSystemElement 70 | // ================================================================== 71 | [Abstract, Description ( 72 | "CIM_ManagedSystemElement is the base class for the System " 73 | "Element hierarchy. Membership Criteria: Any distinguishable " 74 | "component of a System is a candidate for inclusion in this " 75 | "class. Examples: software components, such as files; and " 76 | "devices, such as disk drives and controllers, and physical " 77 | "components such as chips and cards.") ] 78 | class CIM_ManagedSystemElement : CIM_ManagedElement 79 | { 80 | [Description ( 81 | "A datetime value indicating when the object was installed. " 82 | "A lack of a value does not indicate that the object is not " 83 | "installed."), 84 | MappingStrings {"MIF.DMTF|ComponentID|001.5"} ] 85 | datetime InstallDate; 86 | [MaxLen (256), Description ( 87 | "The Name property defines the label by which the object is " 88 | "known. When subclassed, the Name property can be overridden " 89 | "to be a Key property.") ] 90 | string Name; 91 | [MaxLen (10), Description ( 92 | " A string indicating the current status of the object. " 93 | "Various operational and non-operational statuses are " 94 | "defined. Operational statuses are \"OK\", \"Degraded\", " 95 | "\"Stressed\" and \"Pred Fail\". \"Stressed\" indicates that " 96 | "the Element is functioning, but needs attention. Examples " 97 | "of \"Stressed\" states are overload, overheated, etc. The " 98 | "condition \"Pred Fail\" (failure predicted) indicates that " 99 | "an Element is functioning properly but predicting a failure " 100 | "in the near future. An example is a SMART-enabled hard " 101 | "drive. \n" 102 | " Non-operational statuses can also be specified. These " 103 | "are \"Error\", \"NonRecover\", \"Starting\", \"Stopping\", " 104 | " \"Stopped\", " 105 | "\"Service\", \"No Contact\" and \"Lost Comm\". \"NonRecover\" " 106 | "indicates that a non-recoverable error has occurred. " 107 | "\"Service\" describes an Element being configured, maintained, " 108 | "cleaned, or otherwise administered. This status could apply " 109 | "during mirror-resilvering of a disk, reload of a user " 110 | "permissions list, or other administrative task. Not all such " 111 | "work is on-line, yet the Element is neither \"OK\" nor in " 112 | "one of the other states. \"No Contact\" indicates that the " 113 | "current instance of the monitoring system has knowledge of " 114 | "this Element but has never been able to establish " 115 | "communications with it. \"Lost Comm\" indicates that " 116 | "the ManagedSystemElement is known to exist and has been " 117 | "contacted successfully in the past, but is currently unreachable." 118 | "\"Stopped\" indicates that the ManagedSystemElement is known " 119 | "to exist, it is not operational (i.e. it is unable to " 120 | "provide service to users), but it has not failed. It has purposely " 121 | "been made non-operational. The Element " 122 | "may have never been \"OK\", the Element may have initiated its " 123 | "own stop, or a management system may have initiated the stop."), 124 | ValueMap {"OK", "Error", "Degraded", "Unknown", "Pred Fail", 125 | "Starting", "Stopping", "Service", "Stressed", 126 | "NonRecover", "No Contact", "Lost Comm", "Stopped"} ] 127 | string Status; 128 | }; 129 | 130 | // ================================================================== 131 | // LogicalElement 132 | // ================================================================== 133 | [Abstract, Description ( 134 | "CIM_LogicalElement is a base class for all the components of " 135 | "a System that represent abstract system components, such " 136 | "as Files, Processes, or system capabilities in the form " 137 | "of Logical Devices.") ] 138 | class CIM_LogicalElement:CIM_ManagedSystemElement 139 | { 140 | }; 141 | 142 | // ================================================================== 143 | // System 144 | // ================================================================== 145 | [Abstract, Description ( 146 | "A CIM_System is a LogicalElement that aggregates an " 147 | "enumerable set of Managed System Elements. The aggregation " 148 | "operates as a functional whole. Within any particular " 149 | "subclass of System, there is a well-defined list of " 150 | "Managed System Element classes whose instances must be " 151 | "aggregated.") ] 152 | class CIM_System:CIM_LogicalElement 153 | { 154 | [Key, MaxLen (256), Description ( 155 | "CreationClassName indicates the name of the class or the " 156 | "subclass used in the creation of an instance. When used " 157 | "with the other key properties of this class, this property " 158 | "allows all instances of this class and its subclasses to " 159 | "be uniquely identified.") ] 160 | string CreationClassName; 161 | [Key, MaxLen (256), Override ("Name"), Description ( 162 | "The inherited Name serves as key of a System instance in " 163 | "an enterprise environment.") ] 164 | string Name; 165 | [MaxLen (64), Description ( 166 | "The System object and its derivatives are Top Level Objects " 167 | "of CIM. They provide the scope for numerous components. " 168 | "Having unique System keys is required. A heuristic can be " 169 | "defined in individual System subclasses to attempt to always " 170 | "generate the same System Name Key. The NameFormat property " 171 | "identifies how the System name was generated, using " 172 | "the subclass' heuristic.") ] 173 | string NameFormat; 174 | [MaxLen (256), Description ( 175 | "A string that provides information on how the primary system " 176 | "owner can be reached (e.g. phone number, email address, " 177 | "...)."), 178 | MappingStrings {"MIF.DMTF|General Information|001.3"} ] 179 | string PrimaryOwnerContact; 180 | [MaxLen (64), Description ( 181 | "The name of the primary system owner."), 182 | MappingStrings {"MIF.DMTF|General Information|001.4"} ] 183 | string PrimaryOwnerName; 184 | [Description ( 185 | "An array (bag) of strings that specify the roles this System " 186 | "plays in the IT-environment. Subclasses of System may " 187 | "override this property to define explicit Roles values. " 188 | "Alternately, a Working Group may describe the heuristics, " 189 | "conventions and guidelines for specifying Roles. For " 190 | "example, for an instance of a networking system, the Roles " 191 | "property might contain the string, 'Switch' or 'Bridge'.") ] 192 | string Roles[]; 193 | }; 194 | 195 | // =================================================================== 196 | // ComputerSystem 197 | // =================================================================== 198 | [Abstract, Description ( 199 | "A class derived from System that is a special collection of " 200 | "ManagedSystemElements. This collection provides " 201 | "compute capabilities and serves as aggregation point to " 202 | "associate one or more of the following elements: FileSystem, " 203 | "OperatingSystem, Processor and Memory (Volatile and/or " 204 | "NonVolatile Storage).") ] 205 | class CIM_ComputerSystem : CIM_System 206 | { 207 | [Override ("NameFormat"), Description ( 208 | "The ComputerSystem object and its derivatives are Top Level " 209 | "Objects of CIM. They provide the scope for numerous " 210 | "components. Having unique System keys is required. " 211 | "A heuristic is defined to create the ComputerSystem Name " 212 | "to attempt to always generate the same Name, independent of " 213 | "discovery protocol. This prevents inventory and management " 214 | "problems where the same asset or entity is discovered " 215 | "multiple times, but can not be resolved to a single object. " 216 | "Use of the heuristic is optional, but recommended.\n\n" 217 | "The NameFormat property identifies how the ComputerSystem " 218 | "Name is generated, using a heuristic. The heuristic is " 219 | "outlined, in detail, in the CIM V2 System Model spec. " 220 | "It assumes that the documented rules are traversed in order, " 221 | "to determine and assign a Name. The NameFormat Values " 222 | "list defines the precedence order for assigning the Computer" 223 | "System Name. Several rules do map to the same Value.\n\n" 224 | "Note that the ComputerSystem Name calculated using the " 225 | "heuristic is the System's key value. Other names can be " 226 | "assigned and used for the ComputerSystem, that better suit " 227 | "a business, using Aliases."), 228 | ValueMap {"Other", "IP", "Dial", "HID", "NWA", "HWA", "X25", 229 | "ISDN", "IPX", "DCC", "ICD", "E.164", "SNA", "OID/OSI"} ] 230 | string NameFormat; 231 | [MaxLen (256), ArrayType ("Indexed"), 232 | Description ( 233 | "OtherIdentifyingInfo captures additional data, beyond " 234 | "System Name information, that could be used to identify " 235 | "a ComputerSystem. One example would be to hold the " 236 | "Fibre Channel World-Wide Name (WWN) of a node. Note that " 237 | "if only the Fibre Channel name is available and is " 238 | "unique (able to be used as the System key), then this " 239 | "property would be NULL and the WWN would become the " 240 | "System key, its data placed in the Name property."), 241 | ModelCorrespondence { 242 | "CIM_ComputerSystem.IdentifyingDescriptions"} ] 243 | string OtherIdentifyingInfo[]; 244 | [ArrayType ("Indexed"), Description ( 245 | "An array of free-form strings providing explanations " 246 | "and details behind the entries in the OtherIdentifying" 247 | "Info array. Note, each entry of this array is related " 248 | "to the entry in OtherIdentifyingInfo that is located at " 249 | "the same index."), 250 | ModelCorrespondence { 251 | "CIM_ComputerSystem.OtherIdentifyingInfo"} ] 252 | string IdentifyingDescriptions[]; 253 | [Description ( 254 | "Enumeration indicating whether the ComputerSystem is " 255 | "a special-purpose System (ie, dedicated to a particular " 256 | "use), versus being 'general purpose'. For example, one " 257 | "could specify that the System is dedicated to \"Print\" " 258 | "(value=11) or acts as a \"Hub\" (value=8)."), 259 | Values {"Not Dedicated", "Unknown", "Other", "Storage", 260 | "Router", "Switch", "Layer 3 Switch", 261 | "Central Office Switch", "Hub", "Access Server", 262 | "Firewall", "Print", "I/O", "Web Caching", "Management"} ] 263 | uint16 Dedicated[]; 264 | }; 265 | 266 | // ================================================================== 267 | // Component 268 | // ================================================================== 269 | [Association, Abstract, Aggregation, Description ( 270 | "CIM_Component is a generic association used to establish " 271 | "'part of' relationships between Managed System Elements. For " 272 | "example, the SystemComponent association defines parts of " 273 | "a System.") ] 274 | class CIM_Component 275 | { 276 | [Aggregate, Key, Description ( 277 | "The parent element in the association.") ] 278 | CIM_ManagedSystemElement REF GroupComponent; 279 | [Key, Description ("The child element in the association.") ] 280 | CIM_ManagedSystemElement REF PartComponent; 281 | }; 282 | 283 | // ================================================================== 284 | // SystemComponent 285 | // ================================================================== 286 | [Association, Aggregation, Description ( 287 | "CIM_SystemComponent is a specialization of the CIM_Component " 288 | "association that establishes 'part of' relationships between " 289 | "a System and the Managed System Elements of which it is " 290 | "composed.") ] 291 | class CIM_SystemComponent:CIM_Component 292 | { 293 | [Override ("GroupComponent"), Aggregate, 294 | Description ("The parent System in the Association.") ] 295 | CIM_System REF GroupComponent; 296 | [Override ("PartComponent"), Description ( 297 | "The child element that is a component of a System.") ] 298 | CIM_ManagedSystemElement REF PartComponent; 299 | }; 300 | 301 | -------------------------------------------------------------------------------- /testfiles/EmbObjGetClass.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | TestCMPI_Instance 11 | 12 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 13 | 14 | 15 | 16 | TestCMPI_Instance 17 | 18 | 19 | 20 | 21 | TRUE 22 | 23 | <CLASS NAME="MyTestClass" > <PROPERTY NAME="KeyProp" TYPE="string"> </PROPERTY> </CLASS> 24 | 25 | 26 | 27 | TRUE 28 | 29 | 30 | 31 | 32 | TestCMPI_Instance 33 | 34 | 35 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 36 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 37 | 38 | 39 | 40 | 41 | TRUE 42 | 43 | 44 | <CLASS NAME="MyTestClass" > <PROPERTY NAME="KeyProp" TYPE="string"> </PROPERTY> </CLASS> 45 | <CLASS NAME="MyTestClass" > <PROPERTY NAME="KeyProp" TYPE="string"> </PROPERTY> </CLASS> 46 | 47 | 48 | 49 | 50 | TRUE 51 | 52 | 53 | 54 | TRUE 55 | 56 | 57 | 58 | 59 | CIMLofasz 60 | 61 | 62 | 63 | 64 | CIMLofasz 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /testfiles/EmbObjGetInstNegative.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 00 11 | 12 | 13 | 14 | 15 | <CLASS NAME="MyTestClass" > <PROPERTY NAME="KeyProp" TYPE="string"> <VALUE></VALUE> </PROPERTY> </CLASS> 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /testfiles/EmbObjGetInstNegative2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 00 11 | 12 | 13 | 14 | 15 | 16 | MyTestClass 17 | 18 | <CLASS NAME="MyTestClass" > <PROPERTY NAME="KeyProp" TYPE="string"> <VALUE></VALUE> </PROPERTY> </CLASS> 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /testfiles/EmbObjGetInstance.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 00 11 | 12 | 13 | 14 | 15 | <CLASS NAME="MyTestClass" > <PROPERTY NAME="KeyProp" TYPE="string"> </PROPERTY> </CLASS> 16 | 17 | 18 | 19 | <CLASS NAME="MyTestClass" > <PROPERTY NAME="KeyProp" TYPE="string"> </PROPERTY> </CLASS> 20 | <CLASS NAME="MyTestClass" > <PROPERTY NAME="KeyProp" TYPE="string"> </PROPERTY> </CLASS> 21 | 22 | 23 | 24 | 25 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 26 | 27 | 28 | 29 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 30 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 31 | 32 | 33 | 34 | 35 | 36 | 37 | Good morning! 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /testfiles/EmbObjMethodRsp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 8 | 9 | 10 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 11 | 12 | 13 | 14 | 15 | 16 | 17 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 18 | <INSTANCE CLASSNAME="TestCMPI_Instance" > <PROPERTY NAME="ElementName" TYPE="string"> </PROPERTY> </INSTANCE> 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /testfiles/EnumClassesInput.xml: -------------------------------------------------------------------------------- 1 | FALSETRUETRUEFALSE 2 | -------------------------------------------------------------------------------- /testfiles/MethodRspWithReference.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | https://[::1]:5999 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | https://[::1]:5999 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Hello 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /testfiles/MultiReqInput.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | FALSE 9 | TRUE 10 | TRUE 11 | 12 | 13 | 14 | 15 | FALSE 16 | TRUE 17 | TRUE 18 | 19 | 20 | 21 | 22 | FALSE 23 | TRUE 24 | TRUE 25 | 26 | 27 | 28 | 29 | FALSE 30 | TRUE 31 | TRUE 32 | 33 | 34 | 35 | 36 | FALSE 37 | TRUE 38 | TRUE 39 | 40 | 41 | 42 | 43 | FALSE 44 | TRUE 45 | TRUE 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /testfiles/MultiReqResp.xml: -------------------------------------------------------------------------------- 1 | truetruetrue2.7.0The CIM_ProductParentChild association defines a parent child hierarchy among Products. For example, a Product may come bundled with other Products.truetrueThe parent Product in the association.trueThe child Product in the association.true2.6.0CIM_CompatibleProduct is an association between Products that can indicate a wide variety of information. For example, it can indicate that the two referenced Products interoperate, that they can be installed together, that one can be the physical container for the other, etc. The string property, CompatibilityDescription, defines how the Products interoperate or are compatible, any limitations regarding interoperability or installation, ...trueThe Product for which compatible offerings are defined.trueThe compatible Product.CompatibilityDescription is a free-form string defining how the two referenced Products interoperate or are compatible, any limitations to compatibility, etc.true2.6.0CIM_ProductProductDependency is an association between two Products, indicating that one must be installed, or must be absent, for the other to function. This is conceptually equivalent to the ServiceServiceDependency association.trueThe required Product.trueThe Product that is dependent on another Product.The nature of the Product dependency. This property describes that the associated Product must be installed (value=2) or must be absent (value=3) in order for the Product to function.0123UnknownOtherProduct Must Be InstalledProduct Must Not Be Installedtrue2.6.0CIM_ProductSupport is an association between Product and SupportAccess that conveys how support is obtained for the Product. This is a many-to-many relationship, implying that various types of Support are available for a Product, and that the same Support object can provide assistance for multiple Products.trueThe Product.trueSupport for the Product.true2.6.0CIM_ProductFRU is an association between Product and FRU that provides information regarding what Product components have been or are being replaced. The association is one to many, conveying that a Product can have many FRUs, and that a particular instance of a FRU is only applied to one (instance of a) Product.true1The Product to which the FRU is applied.trueThe FRU.trueCIM_ProductPhysicalComponenttruetrue2.7.0Indicates the PhysicalElement(s) that make up a Product. This association is deprecated in order to correctly place it in the inheritance hierarchy and align the definition with other new classes that are being added to the model, such as CIM_ProductServiceComponent. ProductPhysicalElements was defined in the original CIM V2.0 release, when a Managed Element and a Component relationship between ManagedElements did not exist.CIM_ProductPhysicalComponent.GroupComponenttruetrue1The Product.CIM_ProductPhysicalComponent.PartComponenttrueThe PhysicalElement which is a part of the Product. 2 | 3 | -------------------------------------------------------------------------------- /testfiles/NestedEmbInst.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | rawhide 10 | 11 | 12 | //rawhide/root/cimv2:LMI_StorageJob.InstanceID="LMI:LMI_StorageJob:1" 13 | 14 | 15 | <INSTANCE CLASSNAME="LMI_StorageJob"> 16 | <PROPERTY NAME="MethodName" TYPE="string"> 17 | </PROPERTY> 18 | <PROPERTY NAME="JobOutParameters" EmbeddedObject="object" TYPE="string"> 19 | </PROPERTY> 20 | <PROPERTY NAME="JobInParameters" EmbeddedObject="object" TYPE="string"> 21 | <VALUE>&lt;INSTANCE CLASSNAME=&quot;CIM_ManagedElement&quot;&gt; 22 | &lt;PROPERTY NAME=&quot;Generation&quot; TYPE=&quot;uint64&quot;&gt; 23 | &lt;/PROPERTY&gt; 24 | &lt;PROPERTY NAME=&quot;ElementName&quot; TYPE=&quot;string&quot;&gt; 25 | &lt;/PROPERTY&gt; 26 | &lt;PROPERTY NAME=&quot;Description&quot; TYPE=&quot;string&quot;&gt; 27 | &lt;/PROPERTY&gt; 28 | &lt;PROPERTY NAME=&quot;Caption&quot; TYPE=&quot;string&quot;&gt; 29 | &lt;/PROPERTY&gt; 30 | &lt;PROPERTY NAME=&quot;InstanceID&quot; TYPE=&quot;string&quot;&gt; 31 | &lt;/PROPERTY&gt; 32 | &lt;PROPERTY.REFERENCE NAME=&quot;Partition&quot;&gt; 33 | &lt;/PROPERTY.REFERENCE&gt; 34 | &lt;PROPERTY.REFERENCE NAME=&quot;Goal&quot;&gt; 35 | &lt;/PROPERTY.REFERENCE&gt; 36 | &lt;PROPERTY.REFERENCE NAME=&quot;Extent&quot;&gt; 37 | &lt;VALUE.REFERENCE&gt; 38 | &lt;LOCALINSTANCEPATH&gt; 39 | &lt;LOCALNAMESPACEPATH&gt; 40 | &lt;NAMESPACE NAME=&quot;root&quot;/&gt; 41 | &lt;NAMESPACE NAME=&quot;cimv2&quot;/&gt; 42 | &lt;/LOCALNAMESPACEPATH&gt; 43 | &lt;INSTANCENAME CLASSNAME=&quot;CIM_StorageExtent&quot;&gt; 44 | &lt;KEYBINDING NAME=&quot;CreationClassName&quot;&gt; 45 | &lt;KEYVALUE VALUETYPE=&quot;string&quot;&gt;LMI_StorageExtent&lt;/KEYVALUE&gt; 46 | &lt;/KEYBINDING&gt; 47 | &lt;KEYBINDING NAME=&quot;SystemName&quot;&gt; 48 | &lt;KEYVALUE VALUETYPE=&quot;string&quot;&gt;rawhide&lt;/KEYVALUE&gt; 49 | &lt;/KEYBINDING&gt; 50 | &lt;KEYBINDING NAME=&quot;DeviceID&quot;&gt; 51 | &lt;KEYVALUE VALUETYPE=&quot;string&quot;&gt;/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-1&lt;/KEYVALUE&gt; 52 | &lt;/KEYBINDING&gt; 53 | &lt;KEYBINDING NAME=&quot;SystemCreationClassName&quot;&gt; 54 | &lt;KEYVALUE VALUETYPE=&quot;string&quot;&gt;Linux_ComputerSystem&lt;/KEYVALUE&gt; 55 | &lt;/KEYBINDING&gt; 56 | &lt;/INSTANCENAME&gt; 57 | &lt;/LOCALINSTANCEPATH&gt; 58 | &lt;/VALUE.REFERENCE&gt; 59 | &lt;/PROPERTY.REFERENCE&gt; 60 | &lt;PROPERTY NAME=&quot;Size&quot; TYPE=&quot;uint64&quot;&gt; 61 | &lt;VALUE&gt;10000000&lt;/VALUE&gt; 62 | &lt;/PROPERTY&gt; 63 | &lt;/INSTANCE&gt; 64 | </VALUE> 65 | </PROPERTY> 66 | <PROPERTY NAME="InstanceID" TYPE="string"> 67 | <VALUE>LMI:LMI_StorageJob:1</VALUE> 68 | </PROPERTY> 69 | <PROPERTY NAME="Generation" TYPE="uint64"> 70 | </PROPERTY> 71 | <PROPERTY NAME="ElementName" TYPE="string"> 72 | </PROPERTY> 73 | <PROPERTY NAME="Description" TYPE="string"> 74 | <VALUE>CREATE PARTITION ON /dev/sdb</VALUE> 75 | </PROPERTY> 76 | <PROPERTY NAME="Caption" TYPE="string"> 77 | </PROPERTY> 78 | <PROPERTY NAME="InstallDate" TYPE="datetime"> 79 | </PROPERTY> 80 | <PROPERTY.ARRAY NAME="StatusDescriptions" TYPE="string"> 81 | </PROPERTY.ARRAY> 82 | <PROPERTY NAME="Status" TYPE="string"> 83 | </PROPERTY> 84 | <PROPERTY NAME="HealthState" TYPE="uint16"> 85 | </PROPERTY> 86 | <PROPERTY NAME="CommunicationStatus" TYPE="uint16"> 87 | </PROPERTY> 88 | <PROPERTY NAME="DetailedStatus" TYPE="uint16"> 89 | </PROPERTY> 90 | <PROPERTY NAME="OperatingStatus" TYPE="uint16"> 91 | </PROPERTY> 92 | <PROPERTY NAME="PrimaryStatus" TYPE="uint16"> 93 | </PROPERTY> 94 | <PROPERTY NAME="JobStatus" TYPE="string"> 95 | </PROPERTY> 96 | <PROPERTY NAME="ScheduledStartTime" TYPE="datetime"> 97 | </PROPERTY> 98 | <PROPERTY NAME="JobRunTimes" TYPE="uint32"> 99 | <VALUE>1</VALUE> 100 | </PROPERTY> 101 | <PROPERTY NAME="RunMonth" TYPE="uint8"> 102 | </PROPERTY> 103 | <PROPERTY NAME="RunDay" TYPE="sint8"> 104 | </PROPERTY> 105 | <PROPERTY NAME="RunDayOfWeek" TYPE="sint8"> 106 | </PROPERTY> 107 | <PROPERTY NAME="RunStartInterval" TYPE="datetime"> 108 | </PROPERTY> 109 | <PROPERTY NAME="UntilTime" TYPE="datetime"> 110 | </PROPERTY> 111 | <PROPERTY NAME="Notify" TYPE="string"> 112 | </PROPERTY> 113 | <PROPERTY NAME="Owner" TYPE="string"> 114 | </PROPERTY> 115 | <PROPERTY NAME="Priority" TYPE="uint32"> 116 | </PROPERTY> 117 | <PROPERTY NAME="ErrorCode" TYPE="uint16"> 118 | </PROPERTY> 119 | <PROPERTY NAME="ErrorDescription" TYPE="string"> 120 | </PROPERTY> 121 | <PROPERTY NAME="RecoveryAction" TYPE="uint16"> 122 | </PROPERTY> 123 | <PROPERTY NAME="OtherRecoveryAction" TYPE="string"> 124 | </PROPERTY> 125 | <PROPERTY NAME="DeleteOnCompletion" TYPE="boolean"> 126 | <VALUE>TRUE</VALUE> 127 | </PROPERTY> 128 | <PROPERTY NAME="ElapsedTime" TYPE="datetime"> 129 | </PROPERTY> 130 | <PROPERTY NAME="JobState" TYPE="uint16"> 131 | <VALUE>4</VALUE> 132 | </PROPERTY> 133 | <PROPERTY NAME="LocalOrUtcTime" TYPE="uint16"> 134 | <VALUE>2</VALUE> 135 | </PROPERTY> 136 | <PROPERTY NAME="Name" TYPE="string"> 137 | <VALUE>CREATE PARTITION ON /dev/sdb</VALUE> 138 | </PROPERTY> 139 | <PROPERTY.ARRAY NAME="OperationalStatus" TYPE="uint16"> 140 | <VALUE.ARRAY> 141 | <VALUE>2</VALUE> 142 | </VALUE.ARRAY> 143 | </PROPERTY.ARRAY> 144 | <PROPERTY NAME="PercentComplete" TYPE="uint16"> 145 | <VALUE>50</VALUE> 146 | </PROPERTY> 147 | <PROPERTY NAME="StartTime" TYPE="datetime"> 148 | <VALUE>20130429103108.468050+000</VALUE> 149 | </PROPERTY> 150 | <PROPERTY NAME="TimeBeforeRemoval" TYPE="datetime"> 151 | <VALUE>00000000000100.000000:000</VALUE> 152 | </PROPERTY> 153 | <PROPERTY NAME="TimeOfLastStateChange" TYPE="datetime"> 154 | <VALUE>20130429103108.468089+000</VALUE> 155 | </PROPERTY> 156 | <PROPERTY NAME="TimeSubmitted" TYPE="datetime"> 157 | <VALUE>20130429103108.458642+000</VALUE> 158 | </PROPERTY> 159 | </INSTANCE> 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 2 170 | 171 | 172 | 173 | 174 | LMI:LMI_StorageJob:Changed 175 | 176 | 177 | sfcb:NO-UUID-FILE-rawhide#20130429103059#20130429103057 178 | 179 | 180 | 0 181 | 182 | 183 | <INSTANCE CLASSNAME="LMI_StorageJob"> 184 | <PROPERTY NAME="MethodName" TYPE="string"> 185 | </PROPERTY> 186 | <PROPERTY NAME="JobOutParameters" EmbeddedObject="object" TYPE="string"> 187 | </PROPERTY> 188 | <PROPERTY NAME="JobInParameters" EmbeddedObject="object" TYPE="string"> 189 | <VALUE>&lt;INSTANCE CLASSNAME=&quot;CIM_ManagedElement&quot;&gt; 190 | &lt;PROPERTY NAME=&quot;Generation&quot; TYPE=&quot;uint64&quot;&gt; 191 | &lt;/PROPERTY&gt; 192 | &lt;PROPERTY NAME=&quot;ElementName&quot; TYPE=&quot;string&quot;&gt; 193 | &lt;/PROPERTY&gt; 194 | &lt;PROPERTY NAME=&quot;Description&quot; TYPE=&quot;string&quot;&gt; 195 | &lt;/PROPERTY&gt; 196 | &lt;PROPERTY NAME=&quot;Caption&quot; TYPE=&quot;string&quot;&gt; 197 | &lt;/PROPERTY&gt; 198 | &lt;PROPERTY NAME=&quot;InstanceID&quot; TYPE=&quot;string&quot;&gt; 199 | &lt;/PROPERTY&gt; 200 | &lt;PROPERTY.REFERENCE NAME=&quot;Partition&quot;&gt; 201 | &lt;/PROPERTY.REFERENCE&gt; 202 | &lt;PROPERTY.REFERENCE NAME=&quot;Goal&quot;&gt; 203 | &lt;/PROPERTY.REFERENCE&gt; 204 | &lt;PROPERTY.REFERENCE NAME=&quot;Extent&quot;&gt; 205 | &lt;VALUE.REFERENCE&gt; 206 | &lt;LOCALINSTANCEPATH&gt; 207 | &lt;LOCALNAMESPACEPATH&gt; 208 | &lt;NAMESPACE NAME=&quot;root&quot;/&gt; 209 | &lt;NAMESPACE NAME=&quot;cimv2&quot;/&gt; 210 | &lt;/LOCALNAMESPACEPATH&gt; 211 | &lt;INSTANCENAME CLASSNAME=&quot;CIM_StorageExtent&quot;&gt; 212 | &lt;KEYBINDING NAME=&quot;CreationClassName&quot;&gt; 213 | &lt;KEYVALUE VALUETYPE=&quot;string&quot;&gt;LMI_StorageExtent&lt;/KEYVALUE&gt; 214 | &lt;/KEYBINDING&gt; 215 | &lt;KEYBINDING NAME=&quot;SystemName&quot;&gt; 216 | &lt;KEYVALUE VALUETYPE=&quot;string&quot;&gt;rawhide&lt;/KEYVALUE&gt; 217 | &lt;/KEYBINDING&gt; 218 | &lt;KEYBINDING NAME=&quot;DeviceID&quot;&gt; 219 | &lt;KEYVALUE VALUETYPE=&quot;string&quot;&gt;/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-1&lt;/KEYVALUE&gt; 220 | &lt;/KEYBINDING&gt; 221 | &lt;KEYBINDING NAME=&quot;SystemCreationClassName&quot;&gt; 222 | &lt;KEYVALUE VALUETYPE=&quot;string&quot;&gt;Linux_ComputerSystem&lt;/KEYVALUE&gt; 223 | &lt;/KEYBINDING&gt; 224 | &lt;/INSTANCENAME&gt; 225 | &lt;/LOCALINSTANCEPATH&gt; 226 | &lt;/VALUE.REFERENCE&gt; 227 | &lt;/PROPERTY.REFERENCE&gt; 228 | &lt;PROPERTY NAME=&quot;Size&quot; TYPE=&quot;uint64&quot;&gt; 229 | &lt;VALUE&gt;10000000&lt;/VALUE&gt; 230 | &lt;/PROPERTY&gt; 231 | &lt;/INSTANCE&gt; 232 | </VALUE> 233 | </PROPERTY> 234 | <PROPERTY NAME="InstanceID" TYPE="string"> 235 | <VALUE>LMI:LMI_StorageJob:1</VALUE> 236 | </PROPERTY> 237 | <PROPERTY NAME="Generation" TYPE="uint64"> 238 | </PROPERTY> 239 | <PROPERTY NAME="ElementName" TYPE="string"> 240 | </PROPERTY> 241 | <PROPERTY NAME="Description" TYPE="string"> 242 | <VALUE>CREATE PARTITION ON /dev/sdb</VALUE> 243 | </PROPERTY> 244 | <PROPERTY NAME="Caption" TYPE="string"> 245 | </PROPERTY> 246 | <PROPERTY NAME="InstallDate" TYPE="datetime"> 247 | </PROPERTY> 248 | <PROPERTY.ARRAY NAME="StatusDescriptions" TYPE="string"> 249 | </PROPERTY.ARRAY> 250 | <PROPERTY NAME="Status" TYPE="string"> 251 | </PROPERTY> 252 | <PROPERTY NAME="HealthState" TYPE="uint16"> 253 | </PROPERTY> 254 | <PROPERTY NAME="CommunicationStatus" TYPE="uint16"> 255 | </PROPERTY> 256 | <PROPERTY NAME="DetailedStatus" TYPE="uint16"> 257 | </PROPERTY> 258 | <PROPERTY NAME="OperatingStatus" TYPE="uint16"> 259 | </PROPERTY> 260 | <PROPERTY NAME="PrimaryStatus" TYPE="uint16"> 261 | </PROPERTY> 262 | <PROPERTY NAME="JobStatus" TYPE="string"> 263 | </PROPERTY> 264 | <PROPERTY NAME="ScheduledStartTime" TYPE="datetime"> 265 | </PROPERTY> 266 | <PROPERTY NAME="JobRunTimes" TYPE="uint32"> 267 | <VALUE>1</VALUE> 268 | </PROPERTY> 269 | <PROPERTY NAME="RunMonth" TYPE="uint8"> 270 | </PROPERTY> 271 | <PROPERTY NAME="RunDay" TYPE="sint8"> 272 | </PROPERTY> 273 | <PROPERTY NAME="RunDayOfWeek" TYPE="sint8"> 274 | </PROPERTY> 275 | <PROPERTY NAME="RunStartInterval" TYPE="datetime"> 276 | </PROPERTY> 277 | <PROPERTY NAME="UntilTime" TYPE="datetime"> 278 | </PROPERTY> 279 | <PROPERTY NAME="Notify" TYPE="string"> 280 | </PROPERTY> 281 | <PROPERTY NAME="Owner" TYPE="string"> 282 | </PROPERTY> 283 | <PROPERTY NAME="Priority" TYPE="uint32"> 284 | </PROPERTY> 285 | <PROPERTY NAME="ErrorCode" TYPE="uint16"> 286 | </PROPERTY> 287 | <PROPERTY NAME="ErrorDescription" TYPE="string"> 288 | </PROPERTY> 289 | <PROPERTY NAME="RecoveryAction" TYPE="uint16"> 290 | </PROPERTY> 291 | <PROPERTY NAME="OtherRecoveryAction" TYPE="string"> 292 | </PROPERTY> 293 | <PROPERTY NAME="DeleteOnCompletion" TYPE="boolean"> 294 | <VALUE>TRUE</VALUE> 295 | </PROPERTY> 296 | <PROPERTY NAME="ElapsedTime" TYPE="datetime"> 297 | </PROPERTY> 298 | <PROPERTY NAME="JobState" TYPE="uint16"> 299 | <VALUE>2</VALUE> 300 | </PROPERTY> 301 | <PROPERTY NAME="LocalOrUtcTime" TYPE="uint16"> 302 | <VALUE>2</VALUE> 303 | </PROPERTY> 304 | <PROPERTY NAME="Name" TYPE="string"> 305 | <VALUE>CREATE PARTITION ON /dev/sdb</VALUE> 306 | </PROPERTY> 307 | <PROPERTY.ARRAY NAME="OperationalStatus" TYPE="uint16"> 308 | <VALUE.ARRAY> 309 | <VALUE>15</VALUE> 310 | </VALUE.ARRAY> 311 | </PROPERTY.ARRAY> 312 | <PROPERTY NAME="PercentComplete" TYPE="uint16"> 313 | <VALUE>0</VALUE> 314 | </PROPERTY> 315 | <PROPERTY NAME="StartTime" TYPE="datetime"> 316 | </PROPERTY> 317 | <PROPERTY NAME="TimeBeforeRemoval" TYPE="datetime"> 318 | <VALUE>00000000000100.000000:000</VALUE> 319 | </PROPERTY> 320 | <PROPERTY NAME="TimeOfLastStateChange" TYPE="datetime"> 321 | <VALUE>20130429103108.458642+000</VALUE> 322 | </PROPERTY> 323 | <PROPERTY NAME="TimeSubmitted" TYPE="datetime"> 324 | <VALUE>20130429103108.458642+000</VALUE> 325 | </PROPERTY> 326 | </INSTANCE> 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | -------------------------------------------------------------------------------- /testfiles/ReturnValue.SVC.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 6 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /testfiles/SVCEnumQualiTypes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | FALSE 9 | 10 | 11 | 12 | -515 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /testfiles/SVCGetClass.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Hello world! 10 | 11 | 12 | 13 | 1224 14 | 15 | 16 | 17 | 38 18 | 19 | 20 | 21 | true 22 | false 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /testfiles/SVCMethodRsp.smpl0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 8 | 9 | 10 | 11 | 12 | 13 | CL3E2289 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | icat 22 | 23 | 24 | IBMTS_Account 25 | 26 | 27 | dummy1 28 | 29 | 30 | IBMTS_Account 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /testfiles/SVCMethodRsp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 42 8 | 9 | 10 | 12 11 | 12 | 13 | true 14 | 15 | 16 | 17 | 20070314160503.566012+010 18 | 00000133102418.001328:000 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /testfiles/ValueTypeEnumInstanceNames.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Hello 11 | 12 | 13 | 14 | 20070314160503.566012+010 15 | 16 | 17 | 00000133102418.******:000 18 | 19 | 20 | 21 | 112233445566778899 22 | 23 | 24 | -20 25 | 26 | 27 | 3.14 28 | 29 | 30 | 31 | false 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /testfiles/createInstance.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | String 10 | 11 | 12 | 42 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /testfiles/enumerateClasses.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | TRUE 10 | 11 | 12 | 2.6.0 13 | 14 | 15 | 16 | long ... 17 | 18 | 19 | 20 | 21 | 22 | 23 | 0 24 | 1 25 | 2 26 | 3 27 | 4 28 | .. 29 | 0x8000.. 30 | 31 | 32 | 33 | 34 | TRUE 35 | 36 | 37 | 38 | 39 | true 40 | 41 | 42 | 43 | 44 | TRUE 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | TRUE 53 | 54 | 55 | This is a local property :) 56 | 57 | 58 | 59 | 60 | This is a local property with PROPAGATED=false :) 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /testfiles/enumerateClassesError.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 1 9 | Password Expired 10 | 117 11 | 12 | 13 | 1 14 | Password Expired 15 | 118 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /testfiles/indicationTest.mof: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [ Description("This is our test class that is just a dummy device") ] 5 | class OW_IndicationProviderTest1 : CIM_LogicalDevice 6 | { 7 | }; 8 | 9 | [ Description("This is our test class that is just a dummy device") ] 10 | class OW_IndicationProviderTest2 : CIM_LogicalDevice 11 | { 12 | }; 13 | 14 | [ Description("This is our test class that is just a dummy device") ] 15 | class OW_IndicationProviderTest3 : CIM_LogicalDevice 16 | { 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /testfiles/remote.mof: -------------------------------------------------------------------------------- 1 | 2 | instance of OpenWBEM_RemoteProviderRegistration 3 | { 4 | InstanceID = "test1"; 5 | NamespaceName = "root/remotetest"; 6 | ClassName = "instancetest"; 7 | ProviderTypes = { 1 }; // instance 8 | Url = "http://localhost:10001"; 9 | AlwaysSendCredentials = false; 10 | UseConnectionCredentials = false; 11 | }; 12 | 13 | instance of OpenWBEM_RemoteProviderRegistration 14 | { 15 | InstanceID = "test2"; 16 | NamespaceName = "root/remotetest"; 17 | ClassName = "instancetest"; 18 | ProviderTypes = { 2 }; // secondary instance 19 | Url = "http://localhost:10002"; 20 | AlwaysSendCredentials = false; 21 | UseConnectionCredentials = false; 22 | }; 23 | 24 | instance of OpenWBEM_RemoteProviderRegistration 25 | { 26 | InstanceID = "test3"; 27 | NamespaceName = "root/remotetest"; 28 | ClassName = "assoctest"; 29 | ProviderTypes = { 3 }; // associator 30 | Url = "http://localhost:10003"; 31 | AlwaysSendCredentials = false; 32 | UseConnectionCredentials = false; 33 | }; 34 | 35 | instance of OpenWBEM_RemoteProviderRegistration 36 | { 37 | InstanceID = "test4"; 38 | NamespaceName = "root/remotetest"; 39 | ClassName = "methodtest"; 40 | ProviderTypes = { 5 }; // method 41 | Url = "http://localhost:10004"; 42 | AlwaysSendCredentials = false; 43 | UseConnectionCredentials = false; 44 | }; 45 | 46 | -------------------------------------------------------------------------------- /testfiles/socketCat/httpHeaderAcceptApplicationStar.in: -------------------------------------------------------------------------------- 1 | M-POST /cimom HTTP/1.1 2 | Host: localhost 3 | User-Agent: openwbem/3.1.1 4 | Content-Type: application/xml; charset="utf-8" 5 | Content-Length: 518 6 | TE: trailers 7 | Accept-Encoding: deflate 8 | Authorization: Basic dGVzdDE6cGFzczE= 9 | Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns=02 10 | 02-CIMOperation: MethodCall 11 | 02-CIMMethod: GetClass 12 | 02-CIMObject: root%2Ftestsuite 13 | Accept: application/* 14 | 15 | FALSETRUE 16 | -------------------------------------------------------------------------------- /testfiles/socketCat/httpHeaderAcceptApplicationXml.in: -------------------------------------------------------------------------------- 1 | M-POST /cimom HTTP/1.1 2 | Host: localhost 3 | User-Agent: openwbem/3.1.1 4 | Content-Type: application/xml; charset="utf-8" 5 | Content-Length: 518 6 | TE: trailers 7 | Accept-Encoding: deflate 8 | Authorization: Basic dGVzdDE6cGFzczE= 9 | Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns=02 10 | 02-CIMOperation: MethodCall 11 | 02-CIMMethod: GetClass 12 | 02-CIMObject: root%2Ftestsuite 13 | Accept: application/xml 14 | 15 | FALSETRUE 16 | -------------------------------------------------------------------------------- /testfiles/socketCat/httpHeaderAcceptBad.in: -------------------------------------------------------------------------------- 1 | M-POST /cimom HTTP/1.1 2 | Host: localhost 3 | User-Agent: openwbem/3.1.1 4 | Content-Type: application/xml; charset="utf-8" 5 | Content-Length: 518 6 | TE: trailers 7 | Accept-Encoding: deflate 8 | Authorization: Basic dGVzdDE6cGFzczE= 9 | Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns=02 10 | 02-CIMOperation: MethodCall 11 | 02-CIMMethod: GetClass 12 | 02-CIMObject: root%2Ftestsuite 13 | Accept: invalid/junk 14 | 15 | FALSETRUE 16 | -------------------------------------------------------------------------------- /testfiles/socketCat/httpHeaderAcceptStarStar.in: -------------------------------------------------------------------------------- 1 | M-POST /cimom HTTP/1.1 2 | Host: localhost 3 | User-Agent: openwbem/3.1.1 4 | Content-Type: application/xml; charset="utf-8" 5 | Content-Length: 518 6 | TE: trailers 7 | Accept-Encoding: deflate 8 | Authorization: Basic dGVzdDE6cGFzczE= 9 | Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns=02 10 | 02-CIMOperation: MethodCall 11 | 02-CIMMethod: GetClass 12 | 02-CIMObject: root%2Ftestsuite 13 | Accept: */* 14 | 15 | FALSETRUE 16 | -------------------------------------------------------------------------------- /testfiles/socketCat/httpHeaderAcceptTextStar.in: -------------------------------------------------------------------------------- 1 | M-POST /cimom HTTP/1.1 2 | Host: localhost 3 | User-Agent: openwbem/3.1.1 4 | Content-Type: application/xml; charset="utf-8" 5 | Content-Length: 518 6 | TE: trailers 7 | Accept-Encoding: deflate 8 | Authorization: Basic dGVzdDE6cGFzczE= 9 | Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns=02 10 | 02-CIMOperation: MethodCall 11 | 02-CIMMethod: GetClass 12 | 02-CIMObject: root%2Ftestsuite 13 | Accept: text/* 14 | 15 | FALSETRUE 16 | -------------------------------------------------------------------------------- /testfiles/socketCat/httpHeaderAcceptTextXml.in: -------------------------------------------------------------------------------- 1 | M-POST /cimom HTTP/1.1 2 | Host: localhost 3 | User-Agent: openwbem/3.1.1 4 | Content-Type: application/xml; charset="utf-8" 5 | Content-Length: 518 6 | TE: trailers 7 | Accept-Encoding: deflate 8 | Authorization: Basic dGVzdDE6cGFzczE= 9 | Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns=02 10 | 02-CIMOperation: MethodCall 11 | 02-CIMMethod: GetClass 12 | 02-CIMObject: root%2Ftestsuite 13 | Accept: text/xml 14 | 15 | FALSETRUE 16 | -------------------------------------------------------------------------------- /testfiles/stringArray.mof: -------------------------------------------------------------------------------- 1 | class simple { 2 | 3 | [read, key] 4 | sint32 clave; 5 | 6 | [read, ArrayType("Indexed")] 7 | string env[]; 8 | }; 9 | 10 | instance of simple { 11 | clave = 1234; 12 | env = {"cad1", "cad2", "cad3"}; 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /testfiles/testsuite.mof: -------------------------------------------------------------------------------- 1 | class S1 { 2 | [Key] string K2; 3 | [Key] string K3; 4 | }; 5 | 6 | instance of S1 7 | { 8 | K2 = "1k2"; 9 | K3 = "1k3"; 10 | }; 11 | 12 | instance of S1 13 | { 14 | K2 = "2k2"; 15 | K3 = "2k3"; 16 | }; 17 | 18 | instance of S1 19 | { 20 | K2 = "3k2"; 21 | K3 = "3k3"; 22 | }; 23 | 24 | class Example_C1 { 25 | [Key] string CK1; 26 | [Propagated("S1.K2"), Key] string CK2; 27 | [Propagated("S1.K3"), Key] string CK3; 28 | string P1; 29 | string P2; 30 | string P3; 31 | }; 32 | 33 | class Example_C2 : Example_C1 { 34 | [Override("P2")] string P2; 35 | string P4; 36 | }; 37 | 38 | class Example_C3 : Example_C2 { 39 | [Override("P2")] string P2; 40 | [Override("P3")] string P3; 41 | string P5; 42 | }; 43 | 44 | instance of Example_C1 45 | { 46 | CK1 = "1k1"; 47 | CK2 = "1k2"; 48 | CK3 = "1k3"; 49 | P1 = "1p1"; 50 | P2 = "1p2"; 51 | P3 = "1p3"; 52 | }; 53 | 54 | instance of Example_C2 55 | { 56 | CK1 = "2k1"; 57 | CK2 = "2k2"; 58 | CK3 = "2k3"; 59 | P1 = "2p1"; 60 | P2 = "2p2"; 61 | P3 = "2p3"; 62 | P4 = "2p4"; 63 | }; 64 | 65 | instance of Example_C3 66 | { 67 | CK1 = "3k1"; 68 | CK2 = "3k2"; 69 | CK3 = "3k3"; 70 | P1 = "3p1"; 71 | P2 = "3p2"; 72 | P3 = "3p3"; 73 | P4 = "3p4"; 74 | P5 = "3p5"; 75 | }; 76 | 77 | -------------------------------------------------------------------------------- /testfiles/wqlTest.mof: -------------------------------------------------------------------------------- 1 | 2 | class wqlTestClass 3 | { 4 | [key] 5 | string name; 6 | 7 | sint32 sint32Data; 8 | boolean booleanData; 9 | uint64 uint64Data; 10 | string stringData; 11 | real64 realData; 12 | 13 | }; 14 | 15 | instance of wqlTestClass 16 | { 17 | name = "test1"; 18 | 19 | sint32Data = 0; 20 | }; 21 | 22 | instance of wqlTestClass 23 | { 24 | name = "test2"; 25 | 26 | sint32Data = 10; 27 | }; 28 | 29 | instance of wqlTestClass 30 | { 31 | name = "test3"; 32 | 33 | booleanData = false; 34 | }; 35 | 36 | instance of wqlTestClass 37 | { 38 | name = "test4"; 39 | 40 | booleanData = true; 41 | }; 42 | 43 | instance of wqlTestClass 44 | { 45 | name = "test5"; 46 | 47 | uint64Data = 5000000000000; 48 | }; 49 | 50 | instance of wqlTestClass 51 | { 52 | name = "test6"; 53 | 54 | uint64Data = 10; 55 | }; 56 | 57 | instance of wqlTestClass 58 | { 59 | name = "test7"; 60 | 61 | stringData = "abc"; 62 | }; 63 | 64 | instance of wqlTestClass 65 | { 66 | name = "test8"; 67 | 68 | stringData = "test"; 69 | }; 70 | 71 | instance of wqlTestClass 72 | { 73 | name = "test9"; 74 | 75 | realData = 123.456789; 76 | }; 77 | 78 | instance of wqlTestClass 79 | { 80 | name = "test10"; 81 | 82 | realData = 4567890123.0e18; 83 | }; 84 | 85 | -------------------------------------------------------------------------------- /testfiles/xml_input/getClassCIM_ERR_INVALID_PARAMETER1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /testfiles/xml_input/getClassCIM_ERR_INVALID_PARAMETER2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /testfiles/xml_input/getClassCIM_ERR_INVALID_PARAMETER3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /testfiles/xml_input/getClassCIM_ERR_INVALID_PARAMETER4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /testfiles/xml_input/getClassCIM_ERR_INVALID_PARAMETER5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /types_test.go: -------------------------------------------------------------------------------- 1 | package gowbem 2 | 3 | import ( 4 | "encoding/json" 5 | "encoding/xml" 6 | "fmt" 7 | "io" 8 | "reflect" 9 | "strings" 10 | "testing" 11 | 12 | "github.com/aryann/difflib" 13 | "github.com/google/go-cmp/cmp" 14 | "github.com/google/go-cmp/cmp/cmpopts" 15 | ) 16 | 17 | func makeLocalNamespace(ss []string) *CimLocalNamespacePath { 18 | names := make([]CimNamespace, 0, len(ss)) 19 | for _, s := range ss { 20 | names = append(names, CimNamespace{XMLName: xml.Name{Space: "", Local: "NAMESPACE"}, Name: s}) 21 | } 22 | return &CimLocalNamespacePath{ 23 | XMLName: xml.Name{Space: "", Local: "LOCALNAMESPACEPATH"}, 24 | Namespaces: names} 25 | } 26 | 27 | func makeLocalClass(ss []string, cls string) *CimLocalClassPath { 28 | return &CimLocalClassPath{NamespacePath: *makeLocalNamespace(ss), 29 | ClassName: CimClassName{Name: cls}} 30 | } 31 | 32 | func makeNamespace(host string, ss []string) *CimNamespacePath { 33 | return &CimNamespacePath{ 34 | XMLName: xml.Name{Space: "", Local: "NAMESPACEPATH"}, 35 | Host: CimHost{XMLName: xml.Name{Space: "", Local: "HOST"}, Value: host}, 36 | LocalNamespacePath: *makeLocalNamespace(ss), 37 | } 38 | } 39 | func makeClass(host string, ss []string, cls string) *CimClassPath { 40 | return &CimClassPath{ 41 | XMLName: xml.Name{Space: "", Local: "CLASSPATH"}, 42 | NamespacePath: *makeNamespace(host, ss), 43 | ClassName: CimClassName{XMLName: xml.Name{Space: "", Local: "CLASSNAME"}, Name: cls}} 44 | } 45 | 46 | func makeInstanceNameWithKV1(cls, k, v, vt string) *CimInstanceName { 47 | return &CimInstanceName{ 48 | ClassName: cls, 49 | KeyValue: &CimKeyValue{ 50 | ValueType: vt, 51 | Value: v, 52 | }} 53 | } 54 | 55 | func makeInstanceNameWithKV2(cls, k, v, vt string) *CimInstanceName { 56 | return &CimInstanceName{ 57 | ClassName: cls, 58 | KeyValue: &CimKeyValue{ 59 | Type: vt, 60 | Value: v, 61 | }} 62 | } 63 | 64 | func makeInstanceNameWithValueRef(cls string, ref *CimValueReference) *CimInstanceName { 65 | return &CimInstanceName{ 66 | ClassName: cls, 67 | ValueReference: ref} 68 | } 69 | 70 | func makeValueRef(factor string) *CimValueReference { 71 | return &CimValueReference{ClassPath: makeClass("192.168.1.23", []string{"a", "b", factor}, "value"+factor)} 72 | } 73 | 74 | func makeQualifier(factor string) CimQualifier { 75 | return CimQualifier{ 76 | Name: "CimQualifier_" + factor, 77 | Type: "string", 78 | Propagated: true, 79 | Lang: "cn", 80 | Value: &CimValue{Value: "abc_" + factor}, 81 | } 82 | } 83 | 84 | func makeValueArray(values ...CimValueOrNull) *CimValueArray { 85 | return &CimValueArray{Values: values} 86 | } 87 | func makeValueRefArray(values ...CimValueReferenceOrNull) *CimValueRefArray { 88 | return &CimValueRefArray{XMLName: xml.Name{Space: "", Local: "VALUE.REFARRAY"}, Values: values} 89 | } 90 | 91 | func makeProperty(factor string) *CimAnyProperty { 92 | return &CimAnyProperty{ 93 | Property: &CimProperty{ 94 | Name: "pr_" + factor, 95 | Type: "string", 96 | ClassOrigin: "class_origin" + factor, 97 | Propagated: true, 98 | EmbeddedObject: "object", 99 | Lang: "zh", 100 | Qualifiers: []CimQualifier{makeQualifier("pr" + factor + "q1"), makeQualifier("pr" + factor + "q2")}, 101 | Value: &CimValue{Value: "value" + factor}, 102 | }, 103 | } 104 | } 105 | 106 | func makeInstance(factor string) *CimInstance { 107 | return &CimInstance{ 108 | ClassName: "abc_class" + factor, 109 | Lang: "zh", 110 | Qualifiers: []CimQualifier{makeQualifier("i1"), makeQualifier("i2"), makeQualifier("i3")}, 111 | Properties: []CimAnyProperty{ 112 | *makeProperty(factor + "_1"), 113 | *makeProperty(factor + "_2"), 114 | *makeProperty(factor + "_3"), 115 | }, 116 | } 117 | } 118 | 119 | var paramValues = []CimParamValue{ 120 | 121 | CimParamValue{ 122 | Name: "p1", 123 | ParamType: "string", 124 | EmbeddedObject: "instance", 125 | Value: &CimValue{Value: "value1"}, 126 | }, 127 | 128 | CimParamValue{ 129 | Name: "p2", 130 | ParamType: "string", 131 | EmbeddedObject: "instance", 132 | ValueReference: &CimValueReference{ 133 | ClassPath: makeClass("127.9.2.1", []string{"a", "bc"}, "test_class1"), 134 | }, 135 | }, 136 | 137 | CimParamValue{ 138 | Name: "p3", 139 | ParamType: "string", 140 | EmbeddedObject: "instance", 141 | ValueArray: makeValueArray( 142 | CimValueOrNull{Value: &CimValue{Value: "abc"}}, 143 | CimValueOrNull{Null: &CimValueNull{}}, 144 | CimValueOrNull{Value: &CimValue{Value: "abc"}}, 145 | ), 146 | }, 147 | 148 | CimParamValue{ 149 | Name: "p4", 150 | ParamType: "string", 151 | EmbeddedObject: "instance", 152 | ValueRefArray: makeValueRefArray( 153 | CimValueReferenceOrNull{Value: &CimValueReference{ClassPath: makeClass("127.9.2.1", []string{"a", "bc"}, "test_class1")}}, 154 | CimValueReferenceOrNull{Null: &CimValueNull{}}, 155 | CimValueReferenceOrNull{Value: &CimValueReference{ 156 | InstanceName: &CimInstanceName{ 157 | ClassName: "abc_test", 158 | KeyBindings: []CimKeyBinding{ 159 | CimKeyBinding{ 160 | Name: "kb1", 161 | KeyValue: &CimKeyValue{Type: "string", Value: "kb_value_34"}, 162 | }, 163 | }, 164 | }, 165 | }, 166 | }, 167 | ), 168 | }, 169 | 170 | CimParamValue{ 171 | Name: "p5", 172 | ParamType: "string", 173 | EmbeddedObject: "instance", 174 | ClassName: &CimClassName{Name: "a.b.class_test_p5"}, 175 | }, 176 | 177 | CimParamValue{ 178 | Name: "p6", 179 | ParamType: "string", 180 | EmbeddedObject: "instance", 181 | InstanceName: makeInstanceNameWithKV1("a.b.c.class_test_p6", "k_p6", "v_p6", "string"), 182 | }, 183 | 184 | CimParamValue{ 185 | Name: "p7", 186 | ParamType: "string", 187 | EmbeddedObject: "instance", 188 | Class: &CimClass{ 189 | Name: "a.b.c.class_test_p7", 190 | SuperClass: "a.b.c.class_test_p7_base", 191 | Qualifiers: []CimQualifier{CimQualifier{ 192 | 193 | Name: "CimQualifier_p7_1", 194 | Type: "abc", 195 | Propagated: true, 196 | Lang: "cn", 197 | Value: &CimValue{Value: "abc"}, 198 | CimQualifierFlavor: CimQualifierFlavor{Overridable: true, 199 | ToSubclass: true, 200 | ToInstance: true, 201 | Translatable: true}, 202 | }, 203 | 204 | CimQualifier{ 205 | Name: "CimQualifier_p7_2", 206 | Type: "abc", 207 | Propagated: true, 208 | Lang: "cn", 209 | ValueArray: makeValueArray( 210 | CimValueOrNull{Value: &CimValue{Value: "abc"}}, 211 | ), 212 | }}, 213 | Properties: []CimAnyProperty{ 214 | CimAnyProperty{Property: &CimProperty{ 215 | Name: "pr_p7_1_abc_1", 216 | Type: "string", 217 | ClassOrigin: "pr_p7_1_abc_1_origin", 218 | Propagated: true, 219 | EmbeddedObject: "object", 220 | Lang: "cn", 221 | Value: &CimValue{Value: "vvvvv"}, 222 | }}, 223 | CimAnyProperty{PropertyArray: &CimPropertyArray{ 224 | Name: "pr_p7_1_abc_2", 225 | Type: "string", 226 | ArraySize: 23, 227 | ClassOrigin: "pr_p7_1_abc_2_origin", 228 | Propagated: true, 229 | EmbeddedObject: "object", 230 | Lang: "cn", 231 | ValueArray: makeValueArray( 232 | CimValueOrNull{Value: &CimValue{Value: "vvvvv"}}, 233 | ), 234 | }}, 235 | CimAnyProperty{PropertyReference: &CimPropertyReference{ 236 | Name: "pr_p7_1_abc_3", 237 | ReferenceClass: "ref_class", 238 | ClassOrigin: "pr_p7_1_abc_3_origin", 239 | 240 | Propagated: true, 241 | Qualifiers: []CimQualifier{CimQualifier{ 242 | Name: "CimQualifier_p7_q_1", 243 | Type: "abc", 244 | Propagated: true, 245 | Lang: "cn", 246 | Value: &CimValue{Value: "abc"}, 247 | CimQualifierFlavor: CimQualifierFlavor{Overridable: true, 248 | ToSubclass: true, 249 | ToInstance: true, 250 | Translatable: true}, 251 | }, 252 | 253 | CimQualifier{ 254 | Name: "CimQualifier_p7_q_1", 255 | Type: "abc", 256 | Propagated: true, 257 | Lang: "cn", 258 | ValueArray: makeValueArray( 259 | CimValueOrNull{Value: &CimValue{Value: "abc"}}, 260 | ), 261 | }}, 262 | ValueReference: &CimValueReference{ 263 | LocalInstancePath: &CimLocalInstancePath{ 264 | LocalNamespacePath: *makeLocalNamespace([]string{"f", "t"}), 265 | InstanceName: *makeInstanceNameWithKV2("F.4.A.class_abc", "ref_class", "abcss", "bool"), 266 | }, 267 | }, 268 | }}, 269 | }, 270 | Methods: []CimMethod{ 271 | CimMethod{ 272 | Name: "method_1", 273 | Type: "string", 274 | ClassOrigin: "method_1_origin", 275 | Propagated: true, 276 | Qualifiers: []CimQualifier{ 277 | makeQualifier("m1_q_1"), 278 | makeQualifier("m1_q_2"), 279 | }, 280 | Parameters: []CimAnyParameter{ 281 | CimAnyParameter{Parameter: &CimParameter{ 282 | Name: "method_1_p1", 283 | Type: "string", 284 | Qualifiers: []CimQualifier{ 285 | makeQualifier("m1_q_p1_1"), 286 | makeQualifier("m1_q_p1_2"), 287 | }}}, 288 | CimAnyParameter{Parameter: &CimParameter{ 289 | Name: "method_1_p2", 290 | Type: "string"}}, 291 | CimAnyParameter{ParameterReference: &CimParameterReference{ 292 | Name: "method_1_p3", 293 | ReferenceClass: "string", 294 | Qualifiers: []CimQualifier{ 295 | makeQualifier("m1_q_p3_1"), 296 | makeQualifier("m1_q_p3_2"), 297 | }}}, 298 | CimAnyParameter{ParameterReference: &CimParameterReference{ 299 | Name: "method_1_p4", 300 | ReferenceClass: "string"}}, 301 | CimAnyParameter{ParameterArray: &CimParameterArray{ 302 | Name: "method_1_p5", 303 | Type: "string", 304 | ArraySize: 5, 305 | Qualifiers: []CimQualifier{ 306 | makeQualifier("m1_q_p5_1"), 307 | makeQualifier("m1_q_p5_2"), 308 | }}}, 309 | CimAnyParameter{ParameterArray: &CimParameterArray{ 310 | Name: "method_1_p6", 311 | Type: "string", 312 | ArraySize: 5}}, 313 | 314 | CimAnyParameter{ParameterRefArray: &CimParameterRefArray{ 315 | Name: "method_1_p6", 316 | ReferenceClass: "string", 317 | ArraySize: 6, 318 | Qualifiers: []CimQualifier{ 319 | makeQualifier("m1_q_p6_1"), 320 | makeQualifier("m1_q_p6_2"), 321 | }}}, 322 | 323 | CimAnyParameter{ParameterRefArray: &CimParameterRefArray{ 324 | Name: "method_1_p6", 325 | ReferenceClass: "string", 326 | ArraySize: 6}}, 327 | }, 328 | }, 329 | }, 330 | }, 331 | }, 332 | 333 | CimParamValue{ 334 | Name: "p7", 335 | ParamType: "string", 336 | EmbeddedObject: "instance", 337 | Instance: &CimInstance{ 338 | ClassName: "a.b.c.class_test_p7", 339 | // Properties: []CimAnyProperty{}, 340 | }, 341 | }, 342 | } 343 | 344 | var simple_req1 = CimSimpleReq{ 345 | Correlators: []CimCorrelator{CimCorrelator{Name: "cor1", Type: "string", Value: CimValue{Value: "cor1Value"}}, 346 | CimCorrelator{Name: "cor2", Type: "string", Value: CimValue{Value: "cor2Value"}}}, 347 | MethodCall: &CimMethodCall{ 348 | Name: "abc", 349 | LocalClassPath: makeLocalClass([]string{"a", "b"}, "class1"), 350 | ParamValues: paramValues}, 351 | } 352 | 353 | var simple_req2 = CimSimpleReq{ 354 | Correlators: []CimCorrelator{CimCorrelator{Name: "cor1", Type: "string", Value: CimValue{Value: "cor1Value"}}, 355 | CimCorrelator{Name: "cor2", Type: "string", Value: CimValue{Value: "cor2Value"}}}, 356 | MethodCall: &CimMethodCall{ 357 | Name: "abc", 358 | LocalInstancePath: &CimLocalInstancePath{ 359 | LocalNamespacePath: *makeLocalNamespace([]string{"a", "b"}), 360 | InstanceName: CimInstanceName{ 361 | ClassName: "cls_test23"}, 362 | }, 363 | }, 364 | } 365 | 366 | var simple_req3 = CimSimpleReq{ 367 | IMethodCall: &CimIMethodCall{}, 368 | } 369 | 370 | var req = &CIM{CimVersion: "1.2.3.4", 371 | DtdVersion: "4.5.6.7", 372 | Message: &CimMessage{Id: "12", 373 | ProtocolVersion: "1.2.3.7", 374 | MultiReq: &CimMultiReq{SimpleReqs: []CimSimpleReq{simple_req1, 375 | simple_req2, 376 | simple_req3}, 377 | }, 378 | }} 379 | 380 | func TestMultiReq(t *testing.T) { 381 | bs, e := xml.MarshalIndent(req, "", " ") 382 | if nil != e { 383 | t.Error(e) 384 | return 385 | } else { 386 | t.Log(string(bs)) 387 | } 388 | 389 | var req2 CIM 390 | if e := xml.Unmarshal(bs, &req2); nil != e { 391 | t.Error(e) 392 | return 393 | } 394 | 395 | opts := []cmp.Option{ 396 | cmpopts.IgnoreFields(xml.Name{}, "Local"), 397 | cmpopts.IgnoreUnexported(CIM{}), 398 | } 399 | if !cmp.Equal(*req, req2, opts...) { 400 | t.Error(cmp.Diff(*req, req2, opts...)) 401 | } 402 | 403 | // if !reflect.DeepEqual(req, req2) { 404 | 405 | // bs2, e := xml.MarshalIndent(req2, "", " ") 406 | // if nil != e { 407 | // t.Error(e) 408 | // return 409 | // } else { 410 | 411 | // if string(bs) != string(bs2) { 412 | // t.Errorf("excepted is %#v", req) 413 | // t.Errorf("actual is %#v", req2) 414 | // //t.Log(string(bs)) 415 | 416 | // results := difflib.Diff(strings.Split(string(bs), "\n"), strings.Split(string(bs2), "\n")) 417 | // if 0 != len(results) { 418 | // for _, rec := range results { 419 | // t.Error(rec.String()) 420 | // } 421 | // } 422 | // } 423 | 424 | // } 425 | // } 426 | } 427 | 428 | var simple_rsp1 = CimSimpleRsp{ 429 | IMethodResponse: &CimIMethodResponse{ 430 | Name: "abc", 431 | ParamValues: paramValues, 432 | ReturnValue: &CimIReturnValue{ 433 | ClassNames: []CimClassName{CimClassName{Name: "abc"}}, 434 | }, 435 | }, 436 | } 437 | 438 | var simple_error_rsp = CimSimpleRsp{ 439 | IMethodResponse: &CimIMethodResponse{ 440 | Name: "err_rsp", 441 | //ParamValues: paramValues, 442 | Error: &CimError{Code: 123, Description: "test message"}, 443 | }, 444 | } 445 | 446 | func TestSimpleRsp(t *testing.T) { 447 | for _, rsp := range []CimSimpleRsp{simple_rsp1, simple_error_rsp} { 448 | bs, e := xml.MarshalIndent(rsp, "", " ") 449 | if nil != e { 450 | t.Error(e) 451 | return 452 | } else { 453 | t.Log(string(bs)) 454 | } 455 | 456 | var unmarshal_rsp CimSimpleRsp 457 | if e := xml.Unmarshal(bs, &unmarshal_rsp); nil != e { 458 | t.Error(e) 459 | return 460 | } 461 | 462 | if !reflect.DeepEqual(rsp, unmarshal_rsp) { 463 | 464 | bs2, e := xml.MarshalIndent(unmarshal_rsp, "", " ") 465 | if nil != e { 466 | t.Error(e) 467 | return 468 | } else { 469 | 470 | if string(bs) != string(bs2) { 471 | t.Errorf("excepted is %#v", rsp) 472 | t.Errorf("actual is %#v", unmarshal_rsp) 473 | //t.Log(string(bs)) 474 | 475 | results := difflib.Diff(strings.Split(string(bs), "\n"), strings.Split(string(bs2), "\n")) 476 | if 0 != len(results) { 477 | for _, rec := range results { 478 | t.Error(rec.String()) 479 | } 480 | } 481 | } 482 | } 483 | } 484 | } 485 | } 486 | 487 | func TestCimError(t *testing.T) { 488 | err_txt := ` 489 | 490 | 491 | 492 | 493 | 494 | 495 | ` 496 | 497 | var unmarshal_rsp = CIM{hasFault: func(cim *CIM) error { 498 | if nil == cim.Message { 499 | return messageNotExists 500 | } 501 | if nil == cim.Message.SimpleRsp { 502 | return simpleReqNotExists 503 | } 504 | if nil == cim.Message.SimpleRsp.IMethodResponse { 505 | return imethodResponseNotExists 506 | } 507 | 508 | if nil != cim.Message.SimpleRsp.IMethodResponse.Error { 509 | e := cim.Message.SimpleRsp.IMethodResponse.Error 510 | return WBEMException(CIMStatusCode(e.Code), e.Description) 511 | } 512 | 513 | if nil == cim.Message.SimpleRsp.IMethodResponse.ReturnValue { 514 | return ireturnValueNotExists 515 | } 516 | // if 0 == len(cim.Message.SimpleRsp.IMethodResponse.ReturnValue.Instances) { 517 | // return classesNotExists 518 | // } 519 | return nil 520 | }} 521 | 522 | if e := xml.Unmarshal([]byte(err_txt), &unmarshal_rsp); nil != e { 523 | t.Error(e) 524 | return 525 | } 526 | 527 | //fmt.Println(unmarshal_rsp.Fault()) 528 | //if unmarshal_rsp.Fault() { 529 | //} 530 | 531 | if 100 != unmarshal_rsp.Message.SimpleRsp.IMethodResponse.Error.Code { 532 | t.Error("code is error") 533 | return 534 | } 535 | 536 | t.Log(unmarshal_rsp.Message.SimpleRsp.IMethodResponse.Error.Description) 537 | } 538 | 539 | func TestCimErrorWithInstance(t *testing.T) { 540 | err_txt := ` 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 4 549 | 550 | DMTF 551 | WIPG0204 552 | CIM namespace "root/cimv2" not found. 553 | 554 | root/cimv2EnumerateClasses/root/cimv2 555 | 556 | 2 557 | 0 558 | 559 | 560 | /root/cimv2 561 | 2 562 | 563 | 3 564 | CIM_ERR_INVALID_NAMESPACE 565 | 566 | 567 | 568 | 569 | ` 570 | 571 | var unmarshal_rsp = CIM{hasFault: func(cim *CIM) error { 572 | if nil == cim.Message { 573 | return messageNotExists 574 | } 575 | if nil == cim.Message.SimpleRsp { 576 | return simpleReqNotExists 577 | } 578 | if nil == cim.Message.SimpleRsp.IMethodResponse { 579 | return imethodResponseNotExists 580 | } 581 | 582 | if nil != cim.Message.SimpleRsp.IMethodResponse.Error { 583 | e := cim.Message.SimpleRsp.IMethodResponse.Error 584 | return WBEMException(CIMStatusCode(e.Code), e.Description) 585 | } 586 | 587 | if nil == cim.Message.SimpleRsp.IMethodResponse.ReturnValue { 588 | return ireturnValueNotExists 589 | } 590 | // if 0 == len(cim.Message.SimpleRsp.IMethodResponse.ReturnValue.Instances) { 591 | // return classesNotExists 592 | // } 593 | return nil 594 | }} 595 | 596 | if e := xml.Unmarshal([]byte(err_txt), &unmarshal_rsp); nil != e { 597 | t.Error(e) 598 | return 599 | } 600 | 601 | //fmt.Println(unmarshal_rsp.Fault()) 602 | //if unmarshal_rsp.Fault() { 603 | //} 604 | 605 | if 3 != unmarshal_rsp.Message.SimpleRsp.IMethodResponse.Error.Code { 606 | t.Error("code is error") 607 | return 608 | } 609 | 610 | t.Log(unmarshal_rsp.Message.SimpleRsp.IMethodResponse.Error.Description) 611 | } 612 | 613 | var class = &CimClass{ 614 | Name: "a.b.c.class_test_p7", 615 | SuperClass: "a.b.c.class_test_p7_base", 616 | 617 | Properties: []CimAnyProperty{ 618 | CimAnyProperty{Property: &CimProperty{ 619 | Name: "pr_p7_1_abc_1", 620 | Type: "string", 621 | ClassOrigin: "pr_p7_1_abc_1_origin", 622 | Propagated: true, 623 | EmbeddedObject: "object", 624 | Lang: "cn", 625 | Value: &CimValue{Value: "vvvvv"}, 626 | }}, 627 | CimAnyProperty{PropertyArray: &CimPropertyArray{ 628 | Name: "pr_p7_1_abc_2", 629 | Type: "string", 630 | ArraySize: 23, 631 | ClassOrigin: "pr_p7_1_abc_2_origin", 632 | Propagated: true, 633 | EmbeddedObject: "object", 634 | Lang: "cn", 635 | ValueArray: makeValueArray( 636 | CimValueOrNull{Value: &CimValue{Value: "vvvvv"}}, 637 | CimValueOrNull{Value: &CimValue{Value: "v222"}}, 638 | ), 639 | }}, 640 | CimAnyProperty{PropertyReference: &CimPropertyReference{ 641 | Name: "pr_p7_1_abc_3", 642 | ReferenceClass: "ref_class", 643 | ClassOrigin: "pr_p7_1_abc_3_origin", 644 | 645 | Propagated: true, 646 | ValueReference: &CimValueReference{ 647 | LocalInstancePath: &CimLocalInstancePath{ 648 | LocalNamespacePath: *makeLocalNamespace([]string{"f", "t"}), 649 | InstanceName: *makeInstanceNameWithKV2("F.4.A.class_abc", "ref_class", "abcss", "bool"), 650 | }, 651 | }, 652 | }}, 653 | }, 654 | } 655 | 656 | func TestCimClass(t *testing.T) { 657 | bs, e := xml.MarshalIndent(class, "", " ") 658 | if nil != e { 659 | t.Error(e) 660 | return 661 | } else { 662 | t.Log(string(bs)) 663 | } 664 | 665 | var cls2 CimClass 666 | if e := xml.Unmarshal(bs, &cls2); nil != e { 667 | t.Error(e) 668 | return 669 | } 670 | 671 | // if strings.Contains(class, "a") { 672 | // t.Log(class) 673 | // } 674 | opts := []cmp.Option{ 675 | cmpopts.IgnoreFields(xml.Name{}, "Local"), 676 | } 677 | if !cmp.Equal(*class, cls2, opts...) { 678 | t.Error(cmp.Diff(*class, cls2, opts...)) 679 | } 680 | 681 | // if !reflect.DeepEqual(class, cls2) { 682 | 683 | // bs2, e := xml.MarshalIndent(cls2, "", " ") 684 | // if nil != e { 685 | 686 | // t.Errorf("excepted is %#v", class) 687 | // t.Errorf("actual is %#v", cls2) 688 | // t.Error(e) 689 | // return 690 | // } else { 691 | 692 | // //if string(bs) != string(bs2) { 693 | 694 | // t.Errorf("excepted is %#v", class) 695 | // t.Errorf("actual is %#v", cls2) 696 | // //t.Log(string(bs)) 697 | 698 | // results := difflib.Diff(strings.Split(string(bs), "\n"), strings.Split(string(bs2), "\n")) 699 | // if 0 != len(results) { 700 | // for _, rec := range results { 701 | // t.Error(rec.String()) 702 | // } 703 | // } 704 | // //} 705 | // } 706 | // } 707 | } 708 | 709 | func TestCimValueArray(t *testing.T) { 710 | pr := CimAnyProperty{PropertyArray: &CimPropertyArray{ 711 | XMLName: xml.Name{Space: "", Local: "PROPERTY.ARRAY"}, 712 | Name: "pr_p7_1_abc_2", 713 | Type: "string", 714 | ArraySize: 23, 715 | ClassOrigin: "pr_p7_1_abc_2_origin", 716 | Propagated: true, 717 | EmbeddedObject: "object", 718 | Lang: "cn", 719 | ValueArray: &CimValueArray{ 720 | XMLName: xml.Name{Space: "", Local: "VALUE.ARRAY"}, 721 | Values: []CimValueOrNull{ 722 | CimValueOrNull{Value: &CimValue{XMLName: xml.Name{Space: "", Local: "VALUE"}, 723 | Value: "vvvvv"}}, 724 | CimValueOrNull{Value: &CimValue{XMLName: xml.Name{Space: "", Local: "VALUE"}, 725 | Value: "v222"}}, 726 | }}, 727 | }} 728 | 729 | bs, e := xml.MarshalIndent(&pr, "", " ") 730 | if nil != e { 731 | t.Error(e) 732 | return 733 | } else { 734 | fmt.Println(string(bs)) 735 | } 736 | 737 | text := ` 738 | 739 | vvvvv 740 | v222 741 | 742 | ` 743 | 744 | var unmarshalPr CimAnyProperty 745 | 746 | e = xml.Unmarshal([]byte(text), &unmarshalPr) 747 | if nil != e && io.EOF != e { 748 | t.Error(e) 749 | return 750 | } 751 | 752 | if !reflect.DeepEqual(&pr, &unmarshalPr) { 753 | 754 | t.Errorf("excepted is %#v", pr) 755 | t.Errorf("actual is %#v", unmarshalPr) 756 | if string(bs) != text { 757 | results := difflib.Diff(strings.Split(string(bs), "\n"), strings.Split(text, "\n")) 758 | if 0 != len(results) { 759 | for _, rec := range results { 760 | t.Error(rec.String()) 761 | } 762 | } 763 | } 764 | } 765 | } 766 | 767 | func TestCimValueRefArray(t *testing.T) { 768 | paramValue := CimParamValue{ 769 | XMLName: xml.Name{Space: "", Local: "PARAMVALUE"}, 770 | Name: "p4", 771 | ParamType: "string", 772 | EmbeddedObject: "instance", 773 | ValueRefArray: makeValueRefArray( 774 | CimValueReferenceOrNull{Value: &CimValueReference{XMLName: xml.Name{Space: "", Local: "VALUE.REFERENCE"}, 775 | ClassPath: makeClass("127.9.2.1", []string{"a", "bc"}, "test_class1")}}, 776 | CimValueReferenceOrNull{Null: &CimValueNull{XMLName: xml.Name{Space: "", Local: "VALUE.NULL"}}}, 777 | CimValueReferenceOrNull{Value: &CimValueReference{ 778 | XMLName: xml.Name{Space: "", Local: "VALUE.REFERENCE"}, 779 | InstanceName: &CimInstanceName{ 780 | XMLName: xml.Name{Space: "", Local: "INSTANCENAME"}, 781 | ClassName: "abc_test", 782 | KeyBindings: []CimKeyBinding{ 783 | CimKeyBinding{ 784 | XMLName: xml.Name{Space: "", Local: "KEYBINDING"}, 785 | Name: "kb1", 786 | KeyValue: &CimKeyValue{XMLName: xml.Name{Space: "", Local: "KEYVALUE"}, Type: "string", Value: "kb_value_34"}, 787 | }, 788 | }, 789 | }, 790 | }, 791 | }), 792 | } 793 | 794 | bs, e := xml.MarshalIndent(¶mValue, "", " ") 795 | if nil != e { 796 | t.Error(e) 797 | return 798 | } else { 799 | fmt.Println(string(bs)) 800 | } 801 | 802 | text := ` 803 | 804 | 805 | 806 | 807 | 127.9.2.1 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | kb_value_34 821 | 822 | 823 | 824 | 825 | ` 826 | 827 | var unmarshal CimParamValue 828 | 829 | e = xml.Unmarshal([]byte(text), &unmarshal) 830 | if nil != e && io.EOF != e { 831 | t.Error(e) 832 | return 833 | } 834 | 835 | if !reflect.DeepEqual(¶mValue, &unmarshal) { 836 | paramValue_bytes, _ := json.Marshal(¶mValue) 837 | unmarshal_bytes, _ := json.Marshal(&unmarshal) 838 | t.Errorf("excepted is %#v", string(paramValue_bytes)) 839 | t.Errorf("actual is %#v", string(unmarshal_bytes)) 840 | if string(bs) != text { 841 | results := difflib.Diff(strings.Split(string(bs), "\n"), strings.Split(text, "\n")) 842 | if 0 != len(results) { 843 | for _, rec := range results { 844 | t.Error(rec.String()) 845 | } 846 | } 847 | } 848 | } 849 | } 850 | 851 | var method = CimMethod{ 852 | Name: "method_1", 853 | Type: "string", 854 | ClassOrigin: "method_1_origin", 855 | Propagated: true, 856 | Qualifiers: []CimQualifier{ 857 | makeQualifier("m1_q_1"), 858 | makeQualifier("m1_q_2"), 859 | }, 860 | Parameters: []CimAnyParameter{ 861 | CimAnyParameter{Parameter: &CimParameter{ 862 | Name: "method_1_p1", 863 | Type: "string", 864 | Qualifiers: []CimQualifier{ 865 | makeQualifier("m1_q_p1_1"), 866 | makeQualifier("m1_q_p1_2"), 867 | }}}, 868 | CimAnyParameter{Parameter: &CimParameter{ 869 | Name: "method_1_p2", 870 | Type: "string"}}, 871 | CimAnyParameter{ParameterReference: &CimParameterReference{ 872 | Name: "method_1_p3", 873 | ReferenceClass: "string", 874 | Qualifiers: []CimQualifier{ 875 | makeQualifier("m1_q_p3_1"), 876 | makeQualifier("m1_q_p3_2"), 877 | }}}, 878 | CimAnyParameter{ParameterReference: &CimParameterReference{ 879 | Name: "method_1_p4", 880 | ReferenceClass: "string"}}, 881 | CimAnyParameter{ParameterArray: &CimParameterArray{ 882 | Name: "method_1_p5", 883 | Type: "string", 884 | ArraySize: 5, 885 | Qualifiers: []CimQualifier{ 886 | makeQualifier("m1_q_p5_1"), 887 | makeQualifier("m1_q_p5_2"), 888 | }}}, 889 | CimAnyParameter{ParameterArray: &CimParameterArray{ 890 | Name: "method_1_p6", 891 | Type: "string", 892 | ArraySize: 5}}, 893 | 894 | CimAnyParameter{ParameterRefArray: &CimParameterRefArray{ 895 | Name: "method_1_p6", 896 | ReferenceClass: "string", 897 | ArraySize: 6, 898 | Qualifiers: []CimQualifier{ 899 | makeQualifier("m1_q_p6_1"), 900 | makeQualifier("m1_q_p6_2"), 901 | }}}, 902 | 903 | CimAnyParameter{ParameterRefArray: &CimParameterRefArray{ 904 | Name: "method_1_p6", 905 | ReferenceClass: "string", 906 | ArraySize: 6}}, 907 | }, 908 | } 909 | 910 | func TestCimMethod(t *testing.T) { 911 | bs, e := xml.MarshalIndent(method, "", " ") 912 | if nil != e { 913 | t.Error(e) 914 | return 915 | } else { 916 | t.Log(string(bs)) 917 | } 918 | 919 | var method2 CimMethod 920 | if e := xml.Unmarshal(bs, &method2); nil != e { 921 | t.Error(e) 922 | return 923 | } 924 | 925 | if !reflect.DeepEqual(method, method2) { 926 | bs2, e := xml.MarshalIndent(method2, "", " ") 927 | if nil != e { 928 | 929 | t.Errorf("excepted is %#v", method) 930 | t.Errorf("actual is %#v", method2) 931 | t.Error(e) 932 | return 933 | } else { 934 | 935 | if string(bs) != string(bs2) { 936 | t.Errorf("excepted is %#v", method) 937 | t.Errorf("actual is %#v", method2) 938 | //t.Log(string(bs)) 939 | 940 | results := difflib.Diff(strings.Split(string(bs), "\n"), strings.Split(string(bs2), "\n")) 941 | if 0 != len(results) { 942 | for _, rec := range results { 943 | t.Error(rec.String()) 944 | } 945 | } 946 | } 947 | } 948 | } 949 | } 950 | 951 | var declaration = CimDeclaration{ 952 | DeclGroups: []CimAnyDeclGroup{ 953 | CimAnyDeclGroup{ 954 | DeclGroup: &CimDeclGroup{ 955 | LocalNamespacePath: makeLocalNamespace([]string{"A", "b"}), 956 | QualifierDeclarations: []CimQualifierDeclaration{ 957 | CimQualifierDeclaration{Name: "abc"}, 958 | CimQualifierDeclaration{Name: "abc1", 959 | CimQualifierFlavor: CimQualifierFlavor{ 960 | Overridable: true, 961 | ToSubclass: true, 962 | ToInstance: true, 963 | Translatable: true, 964 | }, 965 | Type: "string", 966 | IsArray: true, 967 | ArraySize: 12, 968 | Scope: &CimScope{Class: true, 969 | Association: true, 970 | Reference: true, 971 | Property: true, 972 | Method: true, 973 | Parameter: true, 974 | Indication: true}, 975 | Value: &CimValue{Value: "abcvvvv"}, 976 | }, 977 | }, 978 | }, 979 | }, 980 | CimAnyDeclGroup{ 981 | DeclGroup: &CimDeclGroup{ 982 | NamespacePath: makeNamespace("192.168.1.2", []string{"A", "b"}), 983 | QualifierDeclarations: []CimQualifierDeclaration{ 984 | CimQualifierDeclaration{Name: "abc"}, 985 | CimQualifierDeclaration{Name: "abc1", 986 | Type: "string", 987 | IsArray: true, 988 | ArraySize: 12, 989 | Scope: &CimScope{Class: true, 990 | Association: true, 991 | Reference: true, 992 | Property: true, 993 | Method: true, 994 | Parameter: true, 995 | Indication: true}, 996 | ValueArray: makeValueArray( 997 | CimValueOrNull{Value: &CimValue{Value: "abcvvvv1"}}, 998 | CimValueOrNull{Null: &CimValueNull{}}, 999 | CimValueOrNull{Value: &CimValue{Value: "abcvvvv3"}}, 1000 | ), 1001 | }, 1002 | }, 1003 | ValueObjects: []CimValueObject{ 1004 | CimValueObject{Instance: &CimInstance{ 1005 | ClassName: "a_class", 1006 | Lang: "zh", 1007 | }}, 1008 | }, 1009 | }, 1010 | }, 1011 | CimAnyDeclGroup{ 1012 | DeclGroupWithName: &CimDeclGroupWithName{ 1013 | LocalNamespacePath: makeLocalNamespace([]string{"A", "b"}), 1014 | QualifierDeclarations: []CimQualifierDeclaration{ 1015 | CimQualifierDeclaration{Name: "abc"}, 1016 | CimQualifierDeclaration{Name: "abc1", 1017 | Type: "string", 1018 | IsArray: true, 1019 | ArraySize: 12, 1020 | Scope: &CimScope{Class: true, 1021 | Association: true, 1022 | Reference: true, 1023 | Property: true, 1024 | Method: true, 1025 | Parameter: true, 1026 | Indication: true}, 1027 | Value: &CimValue{Value: "abcvvvv"}, 1028 | }, 1029 | }, 1030 | ValueNamedObjects: []CimValueNamedObject{ 1031 | CimValueNamedObject{InstanceName: makeInstanceNameWithValueRef("abc", makeValueRef("delar_1")), 1032 | Instance: makeInstance("declar_vn_2")}, 1033 | CimValueNamedObject{Class: class}, 1034 | CimValueNamedObject{}, 1035 | }, 1036 | }, 1037 | }, 1038 | CimAnyDeclGroup{ 1039 | DeclGroupWithPath: &CimDeclGroupWithPath{}, 1040 | }, 1041 | }, 1042 | } 1043 | 1044 | func TestCimDeclaration(t *testing.T) { 1045 | bs, e := xml.MarshalIndent(declaration, "", " ") 1046 | if nil != e { 1047 | t.Error(e) 1048 | return 1049 | } else { 1050 | t.Log(string(bs)) 1051 | } 1052 | 1053 | var declaration2 CimDeclaration 1054 | if e := xml.Unmarshal(bs, &declaration2); nil != e { 1055 | t.Error(e) 1056 | return 1057 | } 1058 | 1059 | opts := []cmp.Option{ 1060 | cmpopts.IgnoreFields(xml.Name{}, "Local"), 1061 | } 1062 | if !cmp.Equal(declaration, declaration2, opts...) { 1063 | t.Error(cmp.Diff(declaration, declaration2, opts...)) 1064 | } 1065 | } 1066 | -------------------------------------------------------------------------------- /url.go: -------------------------------------------------------------------------------- 1 | package gowbem 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "strconv" 7 | "strings" 8 | 9 | "unicode" 10 | ) 11 | 12 | const ( 13 | state_init = iota 14 | state_property_name_begin 15 | state_property_name 16 | state_property_value_begin 17 | state_property_value_typed_begin 18 | state_property_value_typed_end 19 | state_property_value_qouted_end 20 | state_property_value_qouted 21 | state_property_value_qouted_escaped 22 | state_property_value_unqouted 23 | ) 24 | 25 | func isWhite(c rune) bool { 26 | return unicode.IsSpace(c) 27 | } 28 | 29 | func isNameChar(c rune) bool { 30 | if c == '_' || c == '-' || 31 | c >= 'a' && c <= 'z' || 32 | c >= 'A' && c <= 'Z' || 33 | c >= '0' && c <= '9' { 34 | return true 35 | } 36 | return false 37 | } 38 | 39 | func ParseKeyBindings(s string) (keyBindings CimKeyBindings, e error) { 40 | _, _, keyBindings, e = parse(s, state_property_name_begin) 41 | return 42 | } 43 | 44 | func ParseInstanceName(s string) (*CimInstanceName, error) { 45 | ns, className, keyBindings, e := parse(s, state_init) 46 | if nil != e { 47 | return nil, e 48 | } 49 | if "" != ns { 50 | return nil, errors.New("namespace isn't empty") 51 | } 52 | 53 | return &CimInstanceName{ 54 | ClassName: className, 55 | KeyBindings: keyBindings, 56 | }, nil 57 | } 58 | 59 | func ParseLocalInstancePath(s string) (*CimLocalInstancePath, error) { 60 | ns, className, keyBindings, e := parse(s, state_init) 61 | if nil != e { 62 | return nil, e 63 | } 64 | 65 | return &CimLocalInstancePath{ 66 | LocalNamespacePath: CimLocalNamespacePath{Namespaces: ToCimNamespace(ns)}, 67 | InstanceName: CimInstanceName{ 68 | ClassName: className, 69 | KeyBindings: keyBindings, 70 | }}, nil 71 | } 72 | 73 | func ToCimNamespace(ns string) []CimNamespace { 74 | if "" == ns { 75 | return nil 76 | } 77 | ss := strings.Split(ns, "/") 78 | results := make([]CimNamespace, len(ss)) 79 | for idx, s := range ss { 80 | results[idx].Name = s 81 | } 82 | return results 83 | } 84 | 85 | func Parse(s string) (namespace string, className string, keyBindings CimKeyBindings, e error) { 86 | return parse(s, state_init) 87 | } 88 | 89 | func parse(s string, state int) (namespace string, className string, keyBindings CimKeyBindings, e error) { 90 | var buf bytes.Buffer 91 | namespaceLast := 0 92 | var propertyName string 93 | var propertyType string 94 | 95 | //state := state_init 96 | for idx, c := range s { 97 | switch state { 98 | case state_init: 99 | if isNameChar(c) { 100 | continue 101 | } 102 | if '/' == c { 103 | namespaceLast = buf.Len() 104 | continue 105 | } 106 | if '.' == c { 107 | if 0 != namespaceLast { 108 | namespace = s[:namespaceLast] 109 | className = s[namespaceLast+1 : idx] 110 | } else { 111 | className = s[:idx] 112 | } 113 | state = state_property_name_begin 114 | continue 115 | } 116 | e = errors.New("invalid classpath - `" + s + "` at " + strconv.FormatInt(int64(idx), 10)) 117 | return 118 | case state_property_name_begin: 119 | if ',' == c { 120 | e = errors.New("invalid property - `" + s + "` at " + strconv.FormatInt(int64(idx), 10)) 121 | return 122 | } 123 | buf.Reset() 124 | propertyName = "" 125 | propertyType = "" 126 | state = state_property_name 127 | fallthrough 128 | case state_property_name: 129 | if isNameChar(c) { 130 | buf.WriteRune(c) 131 | continue 132 | } 133 | 134 | if '=' == c { 135 | propertyName = buf.String() 136 | buf.Reset() 137 | state = state_property_value_begin 138 | continue 139 | } 140 | e = errors.New("invalid property name - `" + s + "` at " + strconv.FormatInt(int64(idx), 10)) 141 | return 142 | case state_property_value_begin: 143 | if '"' == c { 144 | state = state_property_value_qouted 145 | continue 146 | } 147 | if '(' == c { 148 | state = state_property_value_typed_begin 149 | continue 150 | } 151 | buf.WriteRune(c) 152 | state = state_property_value_unqouted 153 | case state_property_value_typed_begin: 154 | if ')' == c { 155 | propertyType = buf.String() 156 | buf.Reset() 157 | state = state_property_value_typed_end 158 | continue 159 | } 160 | buf.WriteRune(c) 161 | case state_property_value_typed_end: 162 | if '"' == c { 163 | state = state_property_value_qouted 164 | continue 165 | } 166 | if isNameChar(c) { 167 | buf.WriteRune(c) 168 | state = state_property_value_unqouted 169 | continue 170 | } 171 | e = errors.New("invalid property value - `" + s + "` at " + strconv.FormatInt(int64(idx), 10)) 172 | return 173 | case state_property_value_qouted_end: 174 | if ',' == c { 175 | state = state_property_name_begin 176 | continue 177 | } 178 | e = errors.New("invalid property value - `" + s + "` at " + strconv.FormatInt(int64(idx), 10)) 179 | return 180 | case state_property_value_qouted: 181 | if '"' == c { 182 | keyBindings = append(keyBindings, CimKeyBinding{ 183 | Name: propertyName, 184 | KeyValue: &CimKeyValue{Type: propertyType, Value: buf.String()}, 185 | }) 186 | buf.Reset() 187 | state = state_property_value_qouted_end 188 | continue 189 | } 190 | 191 | if '\'' == c { 192 | state = state_property_value_qouted_escaped 193 | continue 194 | } 195 | buf.WriteRune(c) 196 | case state_property_value_qouted_escaped: 197 | if '"' == c || '\'' == c { 198 | buf.WriteRune(c) 199 | state = state_property_value_qouted 200 | continue 201 | } 202 | e = errors.New("invalid property value, invalid escaped - `" + s + "` at " + strconv.FormatInt(int64(idx), 10)) 203 | return 204 | case state_property_value_unqouted: 205 | if ',' == c { 206 | keyBindings = append(keyBindings, CimKeyBinding{ 207 | Name: propertyName, 208 | KeyValue: &CimKeyValue{Type: propertyType, Value: buf.String()}, 209 | }) 210 | buf.Reset() 211 | state = state_property_name_begin 212 | continue 213 | } 214 | 215 | if isNameChar(c) { 216 | buf.WriteRune(c) 217 | continue 218 | } 219 | e = errors.New("invalid property value - `" + s + "` at " + strconv.FormatInt(int64(idx), 10)) 220 | return 221 | default: 222 | e = errors.New("unknow state - " + strconv.FormatInt(int64(state), 10)) 223 | return 224 | } 225 | } 226 | 227 | switch state { 228 | case state_init: 229 | if 0 != namespaceLast { 230 | byteArray := buf.Bytes() 231 | namespace = string(byteArray[:namespaceLast]) 232 | className = string(byteArray[namespaceLast+1:]) 233 | } else { 234 | className = buf.String() 235 | } 236 | //case state_property_name_begin: 237 | case state_property_name, 238 | state_property_value_begin, 239 | state_property_value_typed_begin, 240 | state_property_value_typed_end: 241 | e = errors.New("property value is missing - `" + s + "`") 242 | 243 | //case state_property_value_qouted_end: 244 | case state_property_value_qouted, state_property_value_qouted_escaped: 245 | e = errors.New("qouted is missing - `" + s + "`") 246 | case state_property_value_unqouted: 247 | 248 | keyBindings = append(keyBindings, CimKeyBinding{ 249 | Name: propertyName, 250 | KeyValue: &CimKeyValue{Type: propertyType, Value: buf.String()}, 251 | }) 252 | //buf.Reset() 253 | //state = state_property_name_begin 254 | } 255 | return 256 | } 257 | 258 | func SplitNamespaces(namespaceName string) []string { 259 | return strings.Split(strings.Replace(namespaceName, "\\", "/", -1), "/") 260 | } 261 | -------------------------------------------------------------------------------- /wbem_dump/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "encoding/xml" 7 | "flag" 8 | "fmt" 9 | "io/ioutil" 10 | "log" 11 | "net/url" 12 | "os" 13 | "path/filepath" 14 | "strconv" 15 | "strings" 16 | "time" 17 | 18 | "github.com/runner-mei/gowbem" 19 | ) 20 | 21 | var ( 22 | schema = flag.String("scheme", "", "url 的 scheme, 当值为空时根据 port 的值自动选择: 5988 = http, 5989 = https, 缺省值为 http") 23 | host = flag.String("host", "192.168.1.157", "主机的 IP 地址") 24 | port = flag.String("port", "0", "主机上 CIM 服务的端口号, 当值为 0 时根据 schema 的值自动选择: http = 5988, https = 5989 ") 25 | path = flag.String("path", "/cimom", "CIM 服务访问路径") 26 | namespace = flag.String("namespace", "", "CIM 的命名空间, 缺省值: root/cimv2") 27 | classname = flag.String("class", "", "CIM 的的类名") 28 | onlyclass = flag.Bool("onlyclass", false, "仅列出类名") 29 | 30 | username = flag.String("username", "root", "用户名") 31 | userpassword = flag.String("password", "root", "用户密码") 32 | output = flag.String("output", "", "结果的输出目录, 缺省值为当前目录") 33 | debug = flag.Bool("debug", true, "是不是在调试") 34 | ) 35 | 36 | func createURI() *url.URL { 37 | return &url.URL{ 38 | Scheme: *schema, 39 | User: url.UserPassword(*username, *userpassword), 40 | Host: *host + ":" + *port, 41 | Path: *path, 42 | } 43 | } 44 | 45 | func main() { 46 | flag.Usage = func() { 47 | fmt.Println("使用方法: wbem_dump -host=192.168.1.157 -port=5988 -username=root -password=rootpwd\r\n" + 48 | "可用选项") 49 | flag.PrintDefaults() 50 | } 51 | flag.Parse() 52 | 53 | if *output == "" { 54 | *output = "./" + *host 55 | } 56 | 57 | if err := os.MkdirAll(*output, 666); err != nil && !os.IsExist(err) { 58 | log.Fatalln(err) 59 | } 60 | 61 | if *debug { 62 | gowbem.SetDebugProvider(&gowbem.FileDebugProvider{Path: *output}) 63 | } 64 | 65 | if *port == "" || *port == "0" { 66 | switch *schema { 67 | case "http": 68 | *port = "5988" 69 | case "https": 70 | *port = "5989" 71 | case "": 72 | *schema = "http" 73 | *port = "5988" 74 | } 75 | } else if *schema == "" { 76 | switch *port { 77 | case "5988": 78 | *schema = "http" 79 | case "5989": 80 | *schema = "https" 81 | } 82 | } 83 | 84 | c, e := gowbem.NewClientCIMXML(createURI(), true) 85 | if nil != e { 86 | log.Fatalln("连接失败,", e) 87 | } 88 | 89 | if *classname != "" && *namespace != "" { 90 | instancePaths := make(map[string]error, 1024) 91 | dumpClass(c, *namespace, *classname, instancePaths) 92 | return 93 | } 94 | 95 | var namespaces []string 96 | timeCtx, _ := context.WithTimeout(context.Background(), 30*time.Second) 97 | 98 | if "" == *namespace { 99 | var err error 100 | namespaces, err = c.EnumerateNamespaces(timeCtx, []string{"root/cimv2"}, 10*time.Second, nil) 101 | if nil != err { 102 | log.Fatalln("连接失败,", err) 103 | } 104 | } else { 105 | namespaces = []string{*namespace} 106 | } 107 | 108 | fmt.Println("命令空间有:", namespaces) 109 | for _, ns := range namespaces { 110 | fmt.Println("开始处理", ns) 111 | dumpNS(c, ns) 112 | } 113 | if len(namespaces) == 0 { 114 | fmt.Println("导出失败!") 115 | os.Exit(1) 116 | return 117 | } 118 | fmt.Println("导出成功!") 119 | } 120 | 121 | func dumpNS(c *gowbem.ClientCIMXML, ns string) { 122 | qualifiers, e := c.EnumerateQualifierTypes(context.Background(), ns) 123 | if nil != e { 124 | fmt.Println("枚举 QualifierType 失败,", e) 125 | // return 126 | } 127 | 128 | if len(qualifiers) > 0 { 129 | nsPath := strings.Replace(ns, "/", "#", -1) 130 | nsPath = strings.Replace(nsPath, "\\", "@", -1) 131 | 132 | /// @begin 将 Qualifier 定义写到文件 133 | filename := filepath.Join(*output, nsPath, "qa.xml") 134 | if err := os.MkdirAll(filepath.Join(*output, nsPath), 666); err != nil && !os.IsExist(err) { 135 | log.Fatalln(err) 136 | } 137 | 138 | var sb bytes.Buffer 139 | sb.WriteString(` 140 | 141 | 142 | `) 143 | for idx := range qualifiers { 144 | sb.WriteString("\r\n") 145 | sb.WriteString(``) 146 | sb.WriteString("\r\n") 147 | 148 | bs, err := xml.MarshalIndent(qualifiers[idx], "", " ") 149 | if err != nil { 150 | log.Fatalln(err) 151 | } 152 | sb.Write(bs) 153 | 154 | sb.WriteString("\r\n") 155 | sb.WriteString(``) 156 | sb.WriteString("\r\n") 157 | } 158 | 159 | sb.WriteString(` 160 | 161 | `) 162 | 163 | if err := ioutil.WriteFile(filename, sb.Bytes(), 666); err != nil { 164 | log.Fatalln(err) 165 | } 166 | /// @end 167 | } 168 | 169 | classNames, e := c.EnumerateClassNames(context.Background(), ns, "", true) 170 | if nil != e { 171 | if !gowbem.IsErrNotSupported(e) && !gowbem.IsEmptyResults(e) { 172 | fmt.Println("枚举类名失败,", e) 173 | } 174 | return 175 | } 176 | if 0 == len(classNames) { 177 | fmt.Println("没有类定义?,") 178 | return 179 | } 180 | 181 | if *onlyclass { 182 | fmt.Println("命令空间 ", ns, "下有:") 183 | for _, className := range classNames { 184 | fmt.Println(className) 185 | } 186 | return 187 | } 188 | 189 | instancePaths := make(map[string]error, 1024) 190 | fmt.Println("命令空间 ", ns, "下有:", classNames) 191 | 192 | for _, className := range classNames { 193 | timeCtx, _ := context.WithTimeout(context.Background(), 30*time.Second) 194 | class, err := c.GetClass(timeCtx, ns, className, true, true, true, nil) 195 | if err != nil { 196 | fmt.Println("取数名失败 - ", err) 197 | } 198 | 199 | nsPath := strings.Replace(ns, "/", "#", -1) 200 | nsPath = strings.Replace(nsPath, "\\", "@", -1) 201 | 202 | /// @begin 将类定义写到文件 203 | filename := filepath.Join(*output, nsPath, className+".xml") 204 | if err := os.MkdirAll(filepath.Join(*output, nsPath), 666); err != nil && !os.IsExist(err) { 205 | log.Fatalln(err) 206 | } 207 | if err := ioutil.WriteFile(filename, []byte(class), 666); err != nil { 208 | log.Fatalln(err) 209 | } 210 | /// @end 211 | 212 | dumpClass(c, ns, className, instancePaths) 213 | } 214 | 215 | for key, err := range instancePaths { 216 | if err != nil { 217 | fmt.Println(key, "获取失败:", err) 218 | } 219 | } 220 | } 221 | 222 | func dumpClass(c *gowbem.ClientCIMXML, ns, className string, instancePaths map[string]error) { 223 | nsPath := strings.Replace(ns, "/", "#", -1) 224 | nsPath = strings.Replace(nsPath, "\\", "@", -1) 225 | 226 | timeCtx, _ := context.WithTimeout(context.Background(), 30*time.Second) 227 | instanceNames, err := c.EnumerateInstanceNames(timeCtx, ns, className) 228 | if err != nil { 229 | 230 | /// @begin 将类定义写到文件 231 | classPath := filepath.Join(*output, nsPath) 232 | if e := os.MkdirAll(classPath, 666); e != nil && !os.IsExist(e) { 233 | log.Fatalln(e) 234 | } 235 | if e := ioutil.WriteFile(filepath.Join(classPath, "error.txt"), []byte(err.Error()), 666); e != nil { 236 | log.Fatalln(e) 237 | } 238 | 239 | fmt.Println(className, 0, err) 240 | 241 | if !gowbem.IsErrNotSupported(err) && !gowbem.IsEmptyResults(err) { 242 | fmt.Println(fmt.Sprintf("%T %v", err, err)) 243 | } 244 | return 245 | } 246 | fmt.Println(className, len(instanceNames)) 247 | 248 | if len(instanceNames) == 0 { 249 | return 250 | } 251 | 252 | /// @begin 将类定义写到文件 253 | classPath := filepath.Join(*output, nsPath, className) 254 | if err := os.MkdirAll(classPath, 666); err != nil && !os.IsExist(err) { 255 | log.Fatalln(err) 256 | } 257 | var buf bytes.Buffer 258 | for _, instanceName := range instanceNames { 259 | buf.WriteString(instanceName.String()) 260 | buf.WriteString("\r\n") 261 | } 262 | if err := ioutil.WriteFile(filepath.Join(classPath, "instances.txt"), buf.Bytes(), 666); err != nil { 263 | log.Fatalln(err) 264 | } 265 | /// @end 266 | 267 | for idx, instanceName := range instanceNames { 268 | if _, exists := instancePaths[instanceName.String()]; exists { 269 | continue 270 | } 271 | 272 | timeCtx, _ := context.WithTimeout(context.Background(), 30*time.Second) 273 | instance, err := c.GetInstanceByInstanceName(timeCtx, ns, instanceName, false, true, true, nil) 274 | if err != nil { 275 | instancePaths[instanceName.String()] = err 276 | 277 | if !gowbem.IsErrNotSupported(err) && !gowbem.IsEmptyResults(err) { 278 | fmt.Println(fmt.Sprintf("%T %v", err, err)) 279 | } 280 | continue 281 | } 282 | 283 | /// @begin 将类定义写到文件 284 | bs, err := xml.MarshalIndent(instance, "", " ") 285 | if err != nil { 286 | log.Fatalln(err) 287 | } 288 | 289 | subclassPath := filepath.Join(*output, nsPath, instanceName.GetClassName()) 290 | if err := os.MkdirAll(subclassPath, 666); err != nil && !os.IsExist(err) { 291 | log.Fatalln(err) 292 | } 293 | 294 | if err := ioutil.WriteFile(filepath.Join(subclassPath, "instance_"+strconv.Itoa(idx)+".xml"), bs, 666); err != nil { 295 | log.Fatalln(err) 296 | } 297 | /// @end 298 | 299 | instancePaths[instanceName.String()] = nil 300 | 301 | // fmt.Println() 302 | // fmt.Println() 303 | // fmt.Println(instanceName.String()) 304 | //for _, k := range instance.GetProperties() { 305 | // fmt.Println(k.GetName(), k.GetValue()) 306 | //} 307 | } 308 | } 309 | --------------------------------------------------------------------------------