| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.cloudstack.storage.datastore.util; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.util.StringTokenizer; |
| |
| import com.cloud.storage.Storage; |
| |
| public class NexentaUtil { |
| public static final String PROVIDER_NAME = "Nexenta"; |
| |
| public static final String NMS_URL = "nmsUrl"; |
| public static final String VOLUME = "volume"; |
| |
| public static final String STORAGE_HOST = "storageHost"; |
| public static final String STORAGE_PORT = "storagePort"; |
| public static final String STORAGE_TYPE = "storageType"; |
| public static final String STORAGE_PATH = "storagePath"; |
| |
| public static final String DEFAULT_NMS_USER = "admin"; |
| public static final String DEFAULT_NMS_PASSWORD = "nexenta"; |
| |
| public static final String SPARSE_VOLUMES = "sparseVolumes"; |
| public static final String VOLUME_BLOCK_SIZE = "volumeBlockSize"; |
| |
| public static final int DEFAULT_NMS_PORT = 2000; |
| public static final int DEFAULT_ISCSI_TARGET_PORTAL_PORT = 3260; |
| public static final int DEFAULT_NFS_PORT = 2049; |
| |
| public static final String ISCSI_TARGET_NAME_PREFIX = "iqn.1986-03.com.sun:02:cloudstack-"; |
| public static final String ISCSI_TARGET_GROUP_PREFIX = "cloudstack/"; |
| |
| /** |
| * Parse NMS url into normalized parts like scheme, user, host and others. |
| * |
| * Example NMS URL: |
| * auto://admin:nexenta@192.168.1.1:2000/ |
| * |
| * NMS URL parts: |
| * auto true if url starts with auto://, protocol will be automatically switched to https if http not supported; |
| * scheme (auto) connection protocol (http or https); |
| * user (admin) NMS user; |
| * password (nexenta) NMS password; |
| * host (192.168.1.1) NMS host; |
| * port (2000) NMS port. |
| * |
| * @param nmsUrl url string to parse |
| * @return instance of NexentaConnection class |
| */ |
| public static NexentaNmsUrl parseNmsUrl(String nmsUrl) { |
| URI uri; |
| |
| try { |
| uri = new URI(nmsUrl); |
| } catch (URISyntaxException e) { |
| throw new IllegalArgumentException("Invalid URI: " + nmsUrl); |
| } |
| |
| boolean isAuto = false; |
| String schema = uri.getScheme(); |
| if (schema == null || schema.isEmpty() || "auto".equalsIgnoreCase(schema)) { |
| schema = "http"; |
| isAuto = true; |
| } |
| |
| String username, password, userInfo = uri.getUserInfo(); |
| if (userInfo == null) { |
| username = DEFAULT_NMS_USER; |
| password = DEFAULT_NMS_PASSWORD; |
| } else { |
| if (userInfo.indexOf(':') < 0) { |
| username = userInfo; |
| password = DEFAULT_NMS_PASSWORD; |
| } else { |
| String[] parts = userInfo.split(":", 2); |
| username = parts[0]; |
| password = parts[1]; |
| } |
| } |
| |
| String host = uri.getHost(); |
| if (host == null) { |
| throw new IllegalArgumentException(String.format("NMS host required: %s.", nmsUrl)); |
| } |
| |
| int port = uri.getPort(); |
| if (port == -1) { |
| port = DEFAULT_NMS_PORT; |
| } |
| |
| return new NexentaNmsUrl(isAuto, schema, username, password, host, port); |
| } |
| |
| public static Storage.StoragePoolType getStorageType(String v) { |
| if ("iSCSI".equalsIgnoreCase(v)) { |
| return Storage.StoragePoolType.Iscsi; |
| } else if ("NFS".equalsIgnoreCase(v)) { |
| return Storage.StoragePoolType.NetworkFilesystem; |
| } |
| return Storage.StoragePoolType.Iscsi; |
| } |
| |
| public static class NexentaPluginParameters { |
| protected NexentaNmsUrl nmsUrl; |
| protected String volume; |
| protected Storage.StoragePoolType storageType = Storage.StoragePoolType.Iscsi; |
| protected String storageHost; |
| protected Integer storagePort; |
| protected String storagePath; |
| protected Boolean sparseVolumes = false; |
| protected String volumeBlockSize = "8K"; |
| |
| public void setNmsUrl(String url) { |
| this.nmsUrl = NexentaUtil.parseNmsUrl(url); |
| } |
| |
| public NexentaNmsUrl getNmsUrl() { |
| return nmsUrl; |
| } |
| |
| public void setVolume(String volume) { |
| if (volume.endsWith("/")) { |
| this.volume = volume.substring(0, volume.length() - 1); |
| } else { |
| this.volume = volume; |
| } |
| } |
| |
| public String getVolume() { |
| return volume; |
| } |
| |
| public void setStorageType(String storageType) { |
| this.storageType = NexentaUtil.getStorageType(storageType); |
| } |
| |
| public Storage.StoragePoolType getStorageType() { |
| return storageType; |
| } |
| |
| public void setStorageHost(String host) { |
| this.storageHost = host; |
| } |
| |
| public String getStorageHost() { |
| if (storageHost == null && nmsUrl != null) { |
| return nmsUrl.getHost(); |
| } |
| return storageHost; |
| } |
| |
| public void setStoragePort(String port) { |
| this.storagePort = Integer.parseInt(port); |
| } |
| |
| public Integer getStoragePort() { |
| if (storagePort == null && storageType != null) { |
| if (storageType == Storage.StoragePoolType.Iscsi) { |
| return DEFAULT_ISCSI_TARGET_PORTAL_PORT; |
| } else { |
| return DEFAULT_NFS_PORT; |
| } |
| } |
| return storagePort; |
| } |
| |
| public void setStoragePath(String path) { |
| this.storagePath = path; |
| } |
| |
| public String getStoragePath() { |
| return storagePath; |
| } |
| |
| public void setSparseVolumes(String sparseVolumes) { |
| this.sparseVolumes = Boolean.TRUE.toString().equalsIgnoreCase(sparseVolumes); |
| } |
| |
| public Boolean isSparseVolumes() { |
| return sparseVolumes; |
| } |
| |
| public void setVolumeBlockSize(String volumeBlockSize) { |
| this.volumeBlockSize = volumeBlockSize; |
| } |
| |
| public String getVolumeBlockSize() { |
| return volumeBlockSize; |
| } |
| } |
| |
| public static NexentaPluginParameters parseNexentaPluginUrl(String url) { |
| final String delimiter1 = ";"; |
| final String delimiter2 = "="; |
| StringTokenizer st = new StringTokenizer(url, delimiter1); |
| NexentaPluginParameters params = new NexentaPluginParameters(); |
| while (st.hasMoreElements()) { |
| String token = st.nextElement().toString(); |
| int idx = token.indexOf(delimiter2); |
| if (idx == -1) { |
| throw new RuntimeException("Invalid URL format"); |
| } |
| String[] urlKeyAndValue = token.split(delimiter2, 2); |
| if (NMS_URL.equalsIgnoreCase(urlKeyAndValue[0])) { |
| params.setNmsUrl(urlKeyAndValue[1]); |
| } else if (VOLUME.equalsIgnoreCase(urlKeyAndValue[0])) { |
| params.setVolume(urlKeyAndValue[1]); |
| } else if (STORAGE_TYPE.equalsIgnoreCase(urlKeyAndValue[0])) { |
| params.setStorageType(urlKeyAndValue[1]); |
| } else if (STORAGE_HOST.equalsIgnoreCase(urlKeyAndValue[0])) { |
| params.setStorageHost(urlKeyAndValue[1]); |
| } else if (STORAGE_PORT.equalsIgnoreCase(urlKeyAndValue[0])) { |
| params.setStoragePort(urlKeyAndValue[1]); |
| } else if (STORAGE_PATH.equalsIgnoreCase(urlKeyAndValue[0])) { |
| params.setStoragePath(urlKeyAndValue[1]); |
| } else if (SPARSE_VOLUMES.equalsIgnoreCase(urlKeyAndValue[0])) { |
| params.setSparseVolumes(urlKeyAndValue[1]); |
| } else if (VOLUME_BLOCK_SIZE.equalsIgnoreCase(urlKeyAndValue[0])) { |
| params.setVolumeBlockSize(urlKeyAndValue[1]); |
| } |
| } |
| return params; |
| } |
| } |