1/*
2Copyright (c) 2017 VMware, Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package object
18
19import (
20	"context"
21	"reflect"
22
23	"github.com/vmware/govmomi/vim25/soap"
24	"github.com/vmware/govmomi/vim25/types"
25)
26
27func init() {
28	types.Add("ArrayOfVirtualDiskInfo", reflect.TypeOf((*arrayOfVirtualDiskInfo)(nil)).Elem())
29
30	types.Add("VirtualDiskInfo", reflect.TypeOf((*VirtualDiskInfo)(nil)).Elem())
31}
32
33type arrayOfVirtualDiskInfo struct {
34	VirtualDiskInfo []VirtualDiskInfo `xml:"VirtualDiskInfo,omitempty"`
35}
36
37type queryVirtualDiskInfoTaskRequest struct {
38	This           types.ManagedObjectReference  `xml:"_this"`
39	Name           string                        `xml:"name"`
40	Datacenter     *types.ManagedObjectReference `xml:"datacenter,omitempty"`
41	IncludeParents bool                          `xml:"includeParents"`
42}
43
44type queryVirtualDiskInfoTaskResponse struct {
45	Returnval types.ManagedObjectReference `xml:"returnval"`
46}
47
48type queryVirtualDiskInfoTaskBody struct {
49	Req *queryVirtualDiskInfoTaskRequest  `xml:"urn:internalvim25 QueryVirtualDiskInfo_Task,omitempty"`
50	Res *queryVirtualDiskInfoTaskResponse `xml:"urn:vim25 QueryVirtualDiskInfo_TaskResponse,omitempty"`
51	Err *soap.Fault                       `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
52}
53
54func (b *queryVirtualDiskInfoTaskBody) Fault() *soap.Fault { return b.Err }
55
56func queryVirtualDiskInfoTask(ctx context.Context, r soap.RoundTripper, req *queryVirtualDiskInfoTaskRequest) (*queryVirtualDiskInfoTaskResponse, error) {
57	var reqBody, resBody queryVirtualDiskInfoTaskBody
58
59	reqBody.Req = req
60
61	if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
62		return nil, err
63	}
64
65	return resBody.Res, nil
66}
67
68type VirtualDiskInfo struct {
69	Name     string `xml:"unit>name"`
70	DiskType string `xml:"diskType"`
71	Parent   string `xml:"parent,omitempty"`
72}
73
74func (m VirtualDiskManager) QueryVirtualDiskInfo(ctx context.Context, name string, dc *Datacenter, includeParents bool) ([]VirtualDiskInfo, error) {
75	req := queryVirtualDiskInfoTaskRequest{
76		This:           m.Reference(),
77		Name:           name,
78		IncludeParents: includeParents,
79	}
80
81	if dc != nil {
82		ref := dc.Reference()
83		req.Datacenter = &ref
84	}
85
86	res, err := queryVirtualDiskInfoTask(ctx, m.Client(), &req)
87	if err != nil {
88		return nil, err
89	}
90
91	info, err := NewTask(m.Client(), res.Returnval).WaitForResult(ctx, nil)
92	if err != nil {
93		return nil, err
94	}
95
96	return info.Result.(arrayOfVirtualDiskInfo).VirtualDiskInfo, nil
97}
98
99type createChildDiskTaskRequest struct {
100	This             types.ManagedObjectReference  `xml:"_this"`
101	ChildName        string                        `xml:"childName"`
102	ChildDatacenter  *types.ManagedObjectReference `xml:"childDatacenter,omitempty"`
103	ParentName       string                        `xml:"parentName"`
104	ParentDatacenter *types.ManagedObjectReference `xml:"parentDatacenter,omitempty"`
105	IsLinkedClone    bool                          `xml:"isLinkedClone"`
106}
107
108type createChildDiskTaskResponse struct {
109	Returnval types.ManagedObjectReference `xml:"returnval"`
110}
111
112type createChildDiskTaskBody struct {
113	Req         *createChildDiskTaskRequest  `xml:"urn:internalvim25 CreateChildDisk_Task,omitempty"`
114	Res         *createChildDiskTaskResponse `xml:"urn:vim25 CreateChildDisk_TaskResponse,omitempty"`
115	InternalRes *createChildDiskTaskResponse `xml:"urn:internalvim25 CreateChildDisk_TaskResponse,omitempty"`
116	Err         *soap.Fault                  `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
117}
118
119func (b *createChildDiskTaskBody) Fault() *soap.Fault { return b.Err }
120
121func createChildDiskTask(ctx context.Context, r soap.RoundTripper, req *createChildDiskTaskRequest) (*createChildDiskTaskResponse, error) {
122	var reqBody, resBody createChildDiskTaskBody
123
124	reqBody.Req = req
125
126	if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
127		return nil, err
128	}
129
130	if resBody.Res != nil {
131		return resBody.Res, nil // vim-version <= 6.5
132	}
133
134	return resBody.InternalRes, nil // vim-version >= 6.7
135}
136
137func (m VirtualDiskManager) CreateChildDisk(ctx context.Context, parent string, pdc *Datacenter, name string, dc *Datacenter, linked bool) (*Task, error) {
138	req := createChildDiskTaskRequest{
139		This:          m.Reference(),
140		ChildName:     name,
141		ParentName:    parent,
142		IsLinkedClone: linked,
143	}
144
145	if dc != nil {
146		ref := dc.Reference()
147		req.ChildDatacenter = &ref
148	}
149
150	if pdc != nil {
151		ref := pdc.Reference()
152		req.ParentDatacenter = &ref
153	}
154
155	res, err := createChildDiskTask(ctx, m.Client(), &req)
156	if err != nil {
157		return nil, err
158	}
159
160	return NewTask(m.Client(), res.Returnval), nil
161}
162