Skip to content

Commit ef728cd

Browse files
Srivastava, PiyushSrivastava, Piyush
authored andcommitted
pull latest main
2 parents 516b553 + b23ac40 commit ef728cd

File tree

18 files changed

+987
-175
lines changed

18 files changed

+987
-175
lines changed

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ private String createCloudStackVolumeForTypeVolume(DataStore dataStore, VolumeIn
137137
CloudStackVolume cloudStackVolume = storageStrategy.createCloudStackVolume(cloudStackVolumeRequest);
138138
if (ProtocolType.ISCSI.name().equalsIgnoreCase(details.get(Constants.PROTOCOL)) && cloudStackVolume.getLun() != null && cloudStackVolume.getLun().getName() != null) {
139139
return cloudStackVolume.getLun().getName();
140-
} else if (ProtocolType.NFS.name().equalsIgnoreCase(details.get(Constants.PROTOCOL))) {
140+
} else if (ProtocolType.NFS3.name().equalsIgnoreCase(details.get(Constants.PROTOCOL))) {
141141
return volumeObject.getUuid(); // return the volume UUID for agent as path for mounting
142142
} else {
143143
String errMsg = "createCloudStackVolumeForTypeVolume: Volume creation failed. Lun or Lun Path is null for dataObject: " + volumeObject;
@@ -160,7 +160,7 @@ public void deleteAsync(DataStore store, DataObject data, AsyncCompletionCallbac
160160
throw new CloudRuntimeException("deleteAsync : Storage Pool not found for id: " + store.getId());
161161
}
162162
Map<String, String> details = storagePoolDetailsDao.listDetailsKeyPairs(store.getId());
163-
if (ProtocolType.NFS.name().equalsIgnoreCase(details.get(Constants.PROTOCOL))) {
163+
if (ProtocolType.NFS3.name().equalsIgnoreCase(details.get(Constants.PROTOCOL))) {
164164
// ManagedNFS qcow2 backing file deletion handled by KVM host/libvirt; nothing to do via ONTAP REST.
165165
s_logger.info("deleteAsync: ManagedNFS volume {} no-op ONTAP deletion", data.getId());
166166
}
@@ -303,7 +303,7 @@ private StorageStrategy getStrategyByStoragePoolDetails(Map<String, String> deta
303303
}
304304
String protocol = details.get(Constants.PROTOCOL);
305305
OntapStorage ontapStorage = new OntapStorage(details.get(Constants.USERNAME), details.get(Constants.PASSWORD),
306-
details.get(Constants.MANAGEMENT_LIF), details.get(Constants.SVM_NAME), ProtocolType.valueOf(protocol),
306+
details.get(Constants.MANAGEMENT_LIF), details.get(Constants.SVM_NAME), Long.parseLong(details.get(Constants.SIZE)), ProtocolType.valueOf(protocol),
307307
Boolean.parseBoolean(details.get(Constants.IS_DISAGGREGATED)));
308308
StorageStrategy storageStrategy = StorageProviderFactory.getStrategy(ontapStorage);
309309
boolean isValid = storageStrategy.connect();

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/FeignConfiguration.java

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.apache.cloudstack.storage.feign;
2121

22+
import com.fasterxml.jackson.databind.ObjectMapper;
2223
import feign.RequestInterceptor;
2324
import feign.Retryer;
2425
import feign.Client;
@@ -30,7 +31,6 @@
3031
import feign.codec.EncodeException;
3132
import com.fasterxml.jackson.core.JsonProcessingException;
3233
import com.fasterxml.jackson.databind.DeserializationFeature;
33-
import com.fasterxml.jackson.databind.ObjectMapper;
3434
import org.apache.http.conn.ConnectionKeepAliveStrategy;
3535
import org.apache.http.conn.ssl.NoopHostnameVerifier;
3636
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
@@ -55,11 +55,11 @@ public class FeignConfiguration {
5555
private final int retryMaxInterval = 5;
5656
private final String ontapFeignMaxConnection = "80";
5757
private final String ontapFeignMaxConnectionPerRoute = "20";
58-
private final ObjectMapper jsonMapper;
58+
private final ObjectMapper objectMapper;
5959

6060
public FeignConfiguration() {
61-
this.jsonMapper = new ObjectMapper();
62-
this.jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
61+
this.objectMapper = new ObjectMapper();
62+
this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
6363
}
6464

6565
public Client createClient() {
@@ -122,7 +122,7 @@ public void encode(Object object, Type bodyType, feign.RequestTemplate template)
122122
return;
123123
}
124124
try {
125-
byte[] jsonBytes = jsonMapper.writeValueAsBytes(object);
125+
byte[] jsonBytes = objectMapper.writeValueAsBytes(object);
126126
template.body(jsonBytes, StandardCharsets.UTF_8);
127127
template.header("Content-Type", "application/json");
128128
} catch (JsonProcessingException e) {
@@ -144,23 +144,7 @@ public Object decode(Response response, Type type) throws IOException, DecodeExc
144144
try (InputStream bodyStream = response.body().asInputStream()) {
145145
json = new String(bodyStream.readAllBytes(), StandardCharsets.UTF_8);
146146
logger.debug("Decoding JSON response: {}", json);
147-
Object result = null;
148-
try {
149-
var javaType = jsonMapper.getTypeFactory().constructType(type);
150-
result = jsonMapper.readValue(json, javaType);
151-
logger.debug("jsonMapper.readValue() completed successfully");
152-
} catch (Throwable ex) {
153-
logger.error("EXCEPTION in jsonMapper.readValue()! Type: {}, Message: {}", ex.getClass().getName(), ex.getMessage(), ex);
154-
throw ex;
155-
}
156-
157-
if (result == null) {
158-
logger.warn("Decoded result is null!");
159-
} else {
160-
logger.debug("Successfully decoded to object of type: {}", result.getClass().getName());
161-
}
162-
logger.debug("Returning result from decoder");
163-
return result;
147+
return objectMapper.readValue(json, objectMapper.getTypeFactory().constructType(type));
164148
} catch (IOException e) {
165149
logger.error("IOException during decoding. Status: {}, Raw body: {}", response.status(), json, e);
166150
throw new DecodeException(response.status(), "Error decoding JSON response", response.request(), e);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.apache.cloudstack.storage.feign.client;
2+
3+
import feign.Headers;
4+
import feign.Param;
5+
import feign.QueryMap;
6+
import feign.RequestLine;
7+
import org.apache.cloudstack.storage.feign.model.IpInterface;
8+
import org.apache.cloudstack.storage.feign.model.response.OntapResponse;
9+
10+
import java.util.Map;
11+
12+
public interface NetworkFeignClient {
13+
@RequestLine("GET /api/network/ip/interfaces")
14+
@Headers({"Authorization: {authHeader}"})
15+
OntapResponse<IpInterface> getNetworkIpInterfaces(@Param("authHeader") String authHeader, @QueryMap Map<String, Object> queryParams);
16+
}

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/client/SANFeignClient.java

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,32 @@
1818
*/
1919
package org.apache.cloudstack.storage.feign.client;
2020

21+
import feign.QueryMap;
2122
import org.apache.cloudstack.storage.feign.model.Igroup;
23+
import org.apache.cloudstack.storage.feign.model.IscsiService;
2224
import org.apache.cloudstack.storage.feign.model.Lun;
2325
import org.apache.cloudstack.storage.feign.model.LunMap;
2426
import org.apache.cloudstack.storage.feign.model.response.OntapResponse;
2527
import feign.Headers;
2628
import feign.Param;
2729
import feign.RequestLine;
28-
import java.net.URI;
30+
import java.util.Map;
2931

3032
//TODO: Proper URLs should be added in the RequestLine annotations below
3133
public interface SANFeignClient {
34+
// iSCSI Service APIs
35+
@RequestLine("GET /api/protocols/san/iscsi/services")
36+
@Headers({"Authorization: {authHeader}"})
37+
OntapResponse<IscsiService> getIscsiServices(@Param("authHeader") String authHeader, @QueryMap Map<String, Object> queryMap);
3238

3339
// LUN Operation APIs
34-
@RequestLine("POST /")
35-
@Headers({"Authorization: {authHeader}", "return_records: {returnRecords}"})
36-
OntapResponse<Lun> createLun(@Param("authHeader") String authHeader,
37-
@Param("returnRecords") boolean returnRecords,
38-
Lun lun);
40+
@RequestLine("POST /api/storage/luns?return_records={returnRecords}")
41+
@Headers({"Authorization: {authHeader}"})
42+
OntapResponse<Lun> createLun(@Param("authHeader") String authHeader, @Param("returnRecords") boolean returnRecords, Lun lun);
3943

40-
@RequestLine("GET /")
44+
@RequestLine("GET /api/storage/luns")
4145
@Headers({"Authorization: {authHeader}"})
42-
OntapResponse<Lun> getLunResponse(@Param("authHeader") String authHeader);
46+
OntapResponse<Lun> getLunResponse(@Param("authHeader") String authHeader, @QueryMap Map<String, Object> queryMap);
4347

4448
@RequestLine("GET /{uuid}")
4549
@Headers({"Authorization: {authHeader}"})
@@ -54,36 +58,35 @@ OntapResponse<Lun> createLun(@Param("authHeader") String authHeader,
5458
void deleteLun(@Param("authHeader") String authHeader, @Param("uuid") String uuid);
5559

5660
// iGroup Operation APIs
57-
@RequestLine("POST /")
58-
@Headers({"Authorization: {authHeader}", "return_records: {returnRecords}"})
59-
OntapResponse<Igroup> createIgroup(@Param("authHeader") String authHeader,
60-
@Param("returnRecords") boolean returnRecords,
61-
Igroup igroupRequest);
61+
@RequestLine("POST /api/protocols/san/igroups?return_records={returnRecords}")
62+
@Headers({"Authorization: {authHeader}"})
63+
OntapResponse<Igroup> createIgroup(@Param("authHeader") String authHeader, @Param("returnRecords") boolean returnRecords, Igroup igroupRequest);
6264

63-
@RequestLine("GET /")
64-
@Headers({"Authorization: {authHeader}"}) // TODO: Check this again, uuid should be part of the path?
65-
OntapResponse<Igroup> getIgroupResponse(@Param("authHeader") String authHeader, @Param("uuid") String uuid);
65+
@RequestLine("GET /api/protocols/san/igroups")
66+
@Headers({"Authorization: {authHeader}"})
67+
OntapResponse<Igroup> getIgroupResponse(@Param("authHeader") String authHeader, @QueryMap Map<String, Object> queryMap);
6668

6769
@RequestLine("GET /{uuid}")
6870
@Headers({"Authorization: {authHeader}"})
6971
Igroup getIgroupByUUID(@Param("authHeader") String authHeader, @Param("uuid") String uuid);
7072

71-
@RequestLine("DELETE /{uuid}")
73+
@RequestLine("DELETE /api/protocols/san/igroups/{uuid}")
7274
@Headers({"Authorization: {authHeader}"})
73-
void deleteIgroup(@Param("baseUri") URI baseUri, @Param("authHeader") String authHeader, @Param("uuid") String uuid);
75+
void deleteIgroup(@Param("authHeader") String authHeader, @Param("uuid") String uuid);
7476

7577
// LUN Maps Operation APIs
76-
@RequestLine("POST /")
77-
@Headers({"Authorization: {authHeader}"})
78-
OntapResponse<LunMap> createLunMap(@Param("authHeader") String authHeader, LunMap lunMap);
78+
@RequestLine("POST /api/protocols/san/lun-maps")
79+
@Headers({"Authorization: {authHeader}", "return_records: {returnRecords}"})
80+
OntapResponse<LunMap> createLunMap(@Param("authHeader") String authHeader, @Param("returnRecords") boolean returnRecords, LunMap lunMap);
81+
7982

80-
@RequestLine("GET /")
83+
@RequestLine("GET /api/protocols/san/lun-maps")
8184
@Headers({"Authorization: {authHeader}"})
82-
OntapResponse<LunMap> getLunMapResponse(@Param("authHeader") String authHeader);
85+
OntapResponse<LunMap> getLunMapResponse(@Param("authHeader") String authHeader, @QueryMap Map<String, Object> queryMap);
8386

84-
@RequestLine("DELETE /{lunUuid}/{igroupUuid}")
87+
@RequestLine("DELETE /api/protocols/san/lun-maps/{lunUuid}/{igroupUuid}")
8588
@Headers({"Authorization: {authHeader}"})
8689
void deleteLunMap(@Param("authHeader") String authHeader,
87-
@Param("lunUuid") String lunUuid,
88-
@Param("igroupUuid") String igroupUuid);
90+
@Param("lunUuid") String lunUUID,
91+
@Param("igroupUuid") String igroupUUID);
8992
}

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/client/VolumeFeignClient.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@ public interface VolumeFeignClient {
3232

3333
@RequestLine("DELETE /api/storage/volumes/{uuid}")
3434
@Headers({"Authorization: {authHeader}"})
35-
void deleteVolume(@Param("authHeader") String authHeader, @Param("uuid") String uuid);
35+
JobResponse deleteVolume(@Param("authHeader") String authHeader, @Param("uuid") String uuid);
3636

3737
@RequestLine("POST /api/storage/volumes")
3838
@Headers({"Authorization: {authHeader}"})
3939
JobResponse createVolumeWithJob(@Param("authHeader") String authHeader, Volume volumeRequest);
4040

41+
@RequestLine("GET /api/storage/volumes")
42+
@Headers({"Authorization: {authHeader}"})
43+
OntapResponse<Volume> getAllVolumes(@Param("authHeader") String authHeader, @QueryMap Map<String, Object> queryParams);
44+
4145
@RequestLine("GET /api/storage/volumes/{uuid}")
4246
@Headers({"Authorization: {authHeader}"})
4347
Volume getVolumeByUUID(@Param("authHeader") String authHeader, @Param("uuid") String uuid);

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/model/Aggregate.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,43 @@
2222
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
2323
import com.fasterxml.jackson.annotation.JsonInclude;
2424
import com.fasterxml.jackson.annotation.JsonProperty;
25+
import com.fasterxml.jackson.annotation.JsonCreator;
26+
import com.fasterxml.jackson.annotation.JsonValue;
2527

2628
import java.util.Objects;
2729

2830
@JsonIgnoreProperties(ignoreUnknown = true)
2931
@JsonInclude(JsonInclude.Include.NON_NULL)
3032
public class Aggregate {
33+
// Replace previous enum with case-insensitive mapping
34+
public enum StateEnum {
35+
ONLINE("online");
36+
private final String value;
37+
38+
StateEnum(String value) {
39+
this.value = value;
40+
}
41+
42+
@JsonValue
43+
public String getValue() {
44+
return value;
45+
}
46+
47+
@Override
48+
public String toString() {
49+
return String.valueOf(value);
50+
}
51+
52+
@JsonCreator
53+
public static StateEnum fromValue(String text) {
54+
for (StateEnum b : StateEnum.values()) {
55+
if (String.valueOf(b.value).equals(text)) {
56+
return b;
57+
}
58+
}
59+
return null;
60+
}
61+
}
3162

3263
@JsonProperty("name")
3364
private String name = null;
@@ -40,6 +71,13 @@ public int hashCode() {
4071
@JsonProperty("uuid")
4172
private String uuid = null;
4273

74+
@JsonProperty("state")
75+
private StateEnum state = null;
76+
77+
@JsonProperty("space")
78+
private AggregateSpace space = null;
79+
80+
4381
public Aggregate name(String name) {
4482
this.name = name;
4583
return this;
@@ -65,6 +103,21 @@ public void setUuid(String uuid) {
65103
this.uuid = uuid;
66104
}
67105

106+
public StateEnum getState() {
107+
return state;
108+
}
109+
110+
public AggregateSpace getSpace() {
111+
return space;
112+
}
113+
114+
public Double getAvailableBlockStorageSpace() {
115+
if (space != null && space.blockStorage != null) {
116+
return space.blockStorage.available;
117+
}
118+
return null;
119+
}
120+
68121

69122
@Override
70123
public boolean equals(java.lang.Object o) {
@@ -95,4 +148,18 @@ public String toString() {
95148
return "DiskAggregates [name=" + name + ", uuid=" + uuid + "]";
96149
}
97150

151+
public static class AggregateSpace {
152+
@JsonProperty("block_storage")
153+
private AggregateSpaceBlockStorage blockStorage = null;
154+
}
155+
156+
public static class AggregateSpaceBlockStorage {
157+
@JsonProperty("available")
158+
private Double available = null;
159+
@JsonProperty("size")
160+
private Double size = null;
161+
@JsonProperty("used")
162+
private Double used = null;
163+
}
164+
98165
}

0 commit comments

Comments
 (0)