// UnmarshalBody extracts the Body from a soap.Envelope and unmarshals to the corresponding govmomi type func UnmarshalBody(data []byte) (*Method, error) { body := struct { Content string `xml:",innerxml"` }{} req := soap.Envelope{ Body: &body, } err := xml.Unmarshal(data, &req) if err != nil { return nil, fmt.Errorf("xml.Unmarshal: %s", err) } decoder := xml.NewDecoder(bytes.NewReader([]byte(body.Content))) decoder.TypeFunc = typeFunc // required to decode interface types var start *xml.StartElement for { tok, derr := decoder.Token() if derr != nil { return nil, fmt.Errorf("decoding body: %s", err) } if t, ok := tok.(xml.StartElement); ok { start = &t break } } kind := start.Name.Local rtype, ok := typeFunc(kind) if !ok { return nil, fmt.Errorf("no vmomi type defined for '%s'", kind) } var val interface{} if rtype != nil { val = reflect.New(rtype).Interface() } err = decoder.DecodeElement(val, start) if err != nil { return nil, fmt.Errorf("decoding %s: %s", kind, err) } method := &Method{Name: kind, Body: val} field := reflect.ValueOf(val).Elem().FieldByName("This") method.This = field.Interface().(types.ManagedObjectReference) return method, nil }
func (e *Executor) Execute(req *types.ExecuteSoap, res interface{}) error { req.This = e.mme.ManagedObjectReference req.Version = "urn:vim25/5.0" x, err := methods.ExecuteSoap(context.TODO(), e.c, req) if err != nil { return err } if x.Returnval != nil { if x.Returnval.Fault != nil { return errors.New(x.Returnval.Fault.FaultMsg) } if err := xml.Unmarshal([]byte(x.Returnval.Response), res); err != nil { return err } } return nil }