1+ // Mount and unmount on the clusters are performed
2+ // on the basis of a new datastore is being added or removed
3+ // This function doesn't account any change in the datastore mount config fields
4+ // Diff is calculated based on different Datastore full reosurce name
5+ func calculateDatastoreMountsDiff(exsitingDatastoreMountCfg, requestedDatastoreMountCfg []interface{}) []interface{} {
6+ existingCfgMap := make(map[string]map[string]interface{})
7+ for _, item := range exsitingDatastoreMountCfg {
8+ m := item. (map[string]interface{})
9+ if datastore, ok := m[" datastore" ]. (string); ok && datastore != " " {
10+ existingCfgMap[datastore] = m
11+ }
12+ }
13+
14+ var diff []interface{}
15+ for _, item := range requestedDatastoreMountCfg {
16+ m := item. (map[string]interface{})
17+ if datastore, ok := m[" datastore" ]. (string); ok && datastore != " " {
18+ if _, exists := existingCfgMap[datastore]; !exists {
19+ diff = append(diff, item)
20+ }
21+ }
22+ }
23+ return diff
24+ }
25+
26+ // For mount and unmount operation, update_mask is not used.
27+ func removeDatastoreMountConfigFieldFromUpdateMask (url string) (string) {
28+
29+ fieldToRemove := " datastoreMountConfig"
30+ encodedComma := " %2C"
31+
32+ // Matches " ,field" to remove the field and the preceding comma.
33+ // e.g. , foo%2CdatastoreMountConfig -> foo
34+ reCommaField := regexp.MustCompile (encodedComma + fieldToRemove)
35+
36+ // Matches " field," to remove the field and the succeeding comma.
37+ // e.g. , datastoreMountConfig%2Cbar -> bar
38+ reFieldComma := regexp.MustCompile (fieldToRemove + encodedComma)
39+
40+ // Matches the field only if it's the entire string.
41+ // e.g. , datastoreMountConfig -> " "
42+ reFieldOnly := regexp.MustCompile (fieldToRemove + ` (?:%20|\+)*$` )
43+
44+ // Remove instances like " ...%2CdatastoreMountConfig"
45+ url = reCommaField.ReplaceAllString (url, " " )
46+
47+ // Remove instances like " datastoreMountConfig%2C..."
48+ url = reFieldComma.ReplaceAllString (url, " " )
49+
50+ // Remove instance where the mask only contains " datastoreMountConfig"
51+ url = reFieldOnly.ReplaceAllString (url, " " )
52+
53+ return url
54+ }
55+
56+ func mountDatastores(mountsToAdd []interface{}, d *schema.ResourceData , config *transport_tpg.Config ) error {
57+ var project string
58+ userAgent, err := tpgresource.GenerateUserAgentString (d, config.UserAgent )
59+ if err != nil {
60+ return err
61+ }
62+
63+ // Mount operations
64+ for _, mount := range mountsToAdd {
65+ mountMap := mount. (map[string]interface{})
66+ datastore, ok := mountMap[" datastore" ]. (string)
67+ if !ok || datastore == " " {
68+ return fmt.Errorf (" no datastore found in the mount request : %#v" , mountMap)
69+ }
70+
71+ datastoreMountConfigPayload := map[string]interface{}{
72+ " datastore" : datastore,
73+ }
74+
75+ if networkData, ok := mountMap[" datastore_network" ]; ok {
76+ datastoreMountConfigPayload[" datastoreNetwork" ] = networkData. ([]interface{})[0]
77+ }
78+ if v, ok := mountMap[" nfs_version" ]; ok && v. (string) != " " {
79+ datastoreMountConfigPayload[" nfsVersion" ] = v. (string)
80+ }
81+ if v, ok := mountMap[" access_mode" ]; ok && v. (string) != " " {
82+ datastoreMountConfigPayload[" accessMode" ] = v. (string)
83+ }
84+
85+ req := map[string]interface{}{
86+ " datastoreMountConfig" : datastoreMountConfigPayload,
87+ }
88+ if v, ok := mountMap[" ignore_colocation" ]; ok {
89+ req[" ignoreColocation" ] = v. (bool)
90+ }
91+
92+ // Construct the URL directly using d.Id () for the resource name
93+ //mountUrl := fmt.Sprintf (" %s%s :mountDatastore" , config.VmwareengineBasePath , d.Id ())
94+ mountUrl, err := tpgresource.ReplaceVars (d, config, " {{" {{" }}VmwareengineBasePath{{" }}" }}{{" {{" }}parent{{" }}" }}/clusters/{{" {{" }}name{{" }}" }}:mountDatastore" )
95+ if err != nil {
96+ return err
97+ }
98+ log.Printf (" [DEBUG] MountDatastore request on a Cluster %q : url: %q reqBody: %#v" , d.Id (), mountUrl, req)
99+ op, err := transport_tpg.SendRequest (transport_tpg.SendRequestOptions {
100+ Config: config,
101+ Method: " POST" ,
102+ RawURL: mountUrl,
103+ UserAgent: userAgent,
104+ Body: req,
105+ Timeout: d.Timeout (schema.TimeoutUpdate ),
106+ })
107+ if err != nil {
108+ return fmt.Errorf (" error calling MountDatastore for %q : %s " , datastore, err)
109+ }
110+
111+ err = VmwareengineOperationWaitTime(
112+ config, op, project, " Mount Datastore" , userAgent,
113+ d.Timeout (schema.TimeoutUpdate ))
114+ if err != nil {
115+ return err
116+ }
117+ }
118+ return nil
119+ }
120+
121+
122+ func unmountDatastores(mountsToRemove []interface{}, d *schema.ResourceData , config *transport_tpg.Config ) error {
123+ var project string
124+ userAgent, err := tpgresource.GenerateUserAgentString (d, config.UserAgent )
125+ if err != nil {
126+ return err
127+ }
128+
129+ // Unmount operations
130+ for _, mount := range mountsToRemove {
131+ mountMap := mount. (map[string]interface{})
132+ datastore, ok := mountMap[" datastore" ]. (string)
133+ if !ok || datastore == " " {
134+ return fmt.Errorf (" no datastore found in the unmount request : %#v" , mountMap)
135+ }
136+
137+ //unmountUrl := fmt.Sprintf (" %s%s :unmountDatastore" , config.VmwareengineBasePath , d.Id ())
138+ unmountUrl, err := tpgresource.ReplaceVars (d, config, " {{" {{" }}VmwareengineBasePath{{" }}" }}{{" {{" }}parent{{" }}" }}/clusters/{{" {{" }}name{{" }}" }}:unmountDatastore" )
139+ if err != nil {
140+ return err
141+ }
142+ req := map[string]interface{}{
143+ " datastore" : datastore,
144+ }
145+
146+ log.Printf (" [DEBUG] UnmountDatastore request on a Cluster %q : url: %q reqBody: %#v" , d.Id (), unmountUrl, req)
147+ op, err := transport_tpg.SendRequest (transport_tpg.SendRequestOptions {
148+ Config: config,
149+ Method: " POST" ,
150+ RawURL: unmountUrl,
151+ UserAgent: userAgent,
152+ Body: req,
153+ Timeout: d.Timeout (schema.TimeoutUpdate ), // Adjust timeout if necessary
154+ })
155+ if err != nil {
156+ return fmt.Errorf (" error calling UnmountDatastore for %q : %s " , datastore, err)
157+ }
158+
159+ // Assuming VmwareengineOperationWaitTime is a function to poll the LRO
160+ err = VmwareengineOperationWaitTime(
161+ config, op, project, " Unmount Datastore" , userAgent,
162+ d.Timeout (schema.TimeoutUpdate )) // Adjust timeout if necessary
163+ if err != nil {
164+ return err
165+ }
166+ log.Printf (" [DEBUG] Successfully unmounted Datastore %q from Cluster %q " , datastore, d.Id ())
167+ }
168+ return nil
169+ }
0 commit comments