From 888b2aead6d38e1840560da5eb4752cd3dcd2a6e Mon Sep 17 00:00:00 2001 From: Vishnu Date: Wed, 29 Jun 2022 06:38:43 +0530 Subject: [PATCH] ZCS-11436: Enhance zmvolume CLI to support S3 volume type - changes in validation of root path in case of external store type --- .../java/com/zimbra/cs/volume/VolumeCLI.java | 76 +++++++++++-------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/store/src/java/com/zimbra/cs/volume/VolumeCLI.java b/store/src/java/com/zimbra/cs/volume/VolumeCLI.java index bce4b19c951..bd397dbbe57 100644 --- a/store/src/java/com/zimbra/cs/volume/VolumeCLI.java +++ b/store/src/java/com/zimbra/cs/volume/VolumeCLI.java @@ -1,7 +1,7 @@ /* * ***** BEGIN LICENSE BLOCK ***** * Zimbra Collaboration Suite Server - * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2016 Synacor, Inc. + * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2016, 2022 Synacor, Inc. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software Foundation, @@ -33,6 +33,7 @@ import com.zimbra.common.util.CliUtil; import com.zimbra.cs.util.BuildInfo; import com.zimbra.cs.util.SoapCLI; +import com.zimbra.cs.volume.Volume.StoreType; import com.zimbra.soap.JaxbUtil; import com.zimbra.soap.admin.message.CreateVolumeRequest; import com.zimbra.soap.admin.message.CreateVolumeResponse; @@ -44,6 +45,7 @@ import com.zimbra.soap.admin.message.ModifyVolumeRequest; import com.zimbra.soap.admin.message.SetCurrentVolumeRequest; import com.zimbra.soap.admin.type.VolumeInfo; +import com.zimbra.soap.admin.type.VolumeExternalInfo; public final class VolumeCLI extends SoapCLI { @@ -60,7 +62,7 @@ public final class VolumeCLI extends SoapCLI { private static final String O_P = "p"; private static final String O_C = "c"; private static final String O_CT = "ct"; - + /** attributes for external storetype **/ private static final String O_ST = "st"; private static final String O_VP = "vp"; @@ -103,6 +105,10 @@ private VolumeCLI() throws ServiceException { private String path; private String compress; private String compressThreshold; + private String storeType; + private String volumePrefix; + private String storageType; + private String bucketId; private void setArgs(CommandLine cl) throws ServiceException, ParseException, IOException { auth = getZAuthToken(cl); @@ -112,6 +118,11 @@ private void setArgs(CommandLine cl) throws ServiceException, ParseException, IO path = cl.getOptionValue(O_P); compress = cl.getOptionValue(O_C); compressThreshold = cl.getOptionValue(O_CT); + storeType = cl.getOptionValue(O_ST); + storeType = storeType == null ? null : storeType.toUpperCase(); + volumePrefix = cl.getOptionValue(O_VP); + storageType = cl.getOptionValue(O_STP); + bucketId = cl.getOptionValue(O_BID); } public static void main(String[] args) { @@ -159,7 +170,7 @@ public static void main(String[] args) { private void setCurrentVolume() throws ParseException, SoapFaultException, IOException, ServiceException, NumberFormatException, HttpException { if (id == null) { - throw new ParseException("id is missing"); + throw new ParseException(A_ID + MISSING_ATTRS); } auth(auth); @@ -226,7 +237,7 @@ private void print(VolumeInfo vol) { private void deleteVolume() throws ParseException, SoapFaultException, IOException, ServiceException, HttpException { if (id == null) { - throw new ParseException("id is missing"); + throw new ParseException(A_ID + MISSING_ATTRS); } DeleteVolumeRequest req = new DeleteVolumeRequest(Short.parseShort(id)); @@ -237,25 +248,18 @@ private void deleteVolume() throws ParseException, SoapFaultException, IOExcepti private void editVolume() throws ParseException, SoapFaultException, IOException, ServiceException, HttpException { if (Strings.isNullOrEmpty(id)) { - throw new ParseException("id is missing"); + throw new ParseException(A_ID + MISSING_ATTRS); } + GetVolumeRequest getVolumeRequest = new GetVolumeRequest(Short.parseShort(id)); + auth(); + GetVolumeResponse getVolumeResponse = JaxbUtil + .elementToJaxb(getTransport().invokeWithoutSession(JaxbUtil.jaxbToElement(getVolumeRequest))); + Volume.StoreType enumStoreType = (1 == getVolumeResponse.getVolume().getStoreType()) ? Volume.StoreType.INTERNAL + : Volume.StoreType.EXTERNAL; + VolumeInfo vol = new VolumeInfo(); - if (!Strings.isNullOrEmpty(type)) { - vol.setType(toType(type)); - } - if (!Strings.isNullOrEmpty(name)) { - vol.setName(name); - } - if (!Strings.isNullOrEmpty(path)) { - vol.setRootPath(path); - } - if (!Strings.isNullOrEmpty(compress)) { - vol.setCompressBlobs(Boolean.parseBoolean(compress)); - } - if (!Strings.isNullOrEmpty(compressThreshold)) { - vol.setCompressionThreshold(Long.parseLong(compressThreshold)); - } + validateEditCommand(vol, enumStoreType); ModifyVolumeRequest req = new ModifyVolumeRequest(Short.parseShort(id), vol); auth(auth); getTransport().invokeWithoutSession(JaxbUtil.jaxbToElement(req)); @@ -264,34 +268,31 @@ private void editVolume() throws ParseException, SoapFaultException, IOException private void addVolume() throws ParseException, SoapFaultException, IOException, ServiceException, HttpException { if (id != null) { - throw new ParseException("id cannot be specified when adding a volume"); + throw new ParseException(NOT_ALLOWED_ID); } if (Strings.isNullOrEmpty(type)) { - throw new ParseException("type is missing"); + throw new ParseException(A_TYPE + MISSING_ATTRS); } if (Strings.isNullOrEmpty(name)) { - throw new ParseException("name is missing"); - } - if (Strings.isNullOrEmpty(path)) { - throw new ParseException("path is missing"); + throw new ParseException(A_NAME + MISSING_ATTRS); } VolumeInfo vol = new VolumeInfo(); vol.setType(toType(type)); vol.setName(name); - vol.setRootPath(path); vol.setCompressBlobs(compress != null ? Boolean.parseBoolean(compress) : false); vol.setCompressionThreshold(compressThreshold != null ? Long.parseLong(compressThreshold) : 4096L); + validateAddCommand(vol); CreateVolumeRequest req = new CreateVolumeRequest(vol); auth(); CreateVolumeResponse resp = JaxbUtil.elementToJaxb(getTransport().invokeWithoutSession( JaxbUtil.jaxbToElement(req))); System.out.println("Volume " + resp.getVolume().getId() + " is created"); } - + /** * This method validate the attributes in edit command. - * + * * @param volumeInfo, volStoreType * @throws ParseException */ @@ -345,7 +346,7 @@ private void validateEditCommand(VolumeInfo volumeInfo, Volume.StoreType volStor /** * This method validate the attributes in add command. - * + * * @param volumeInfo * @throws ParseException */ @@ -361,6 +362,10 @@ private void validateAddCommand(VolumeInfo volumeInfo) throws ParseException { if (!Strings.isNullOrEmpty(volumePrefix)) { throw new ParseException(A_VOLUME_PREFIX + NOT_ALLOWED_INTERNAL); } + if (Strings.isNullOrEmpty(path)) { + throw new ParseException(A_PATH + MISSING_ATTRS); + } + volumeInfo.setRootPath(path); } else if (Volume.StoreType.EXTERNAL.name().equals(storeType)) { VolumeExternalInfo volumeExternalInfo = new VolumeExternalInfo(); if (!Strings.isNullOrEmpty(storageType)) { @@ -406,6 +411,10 @@ protected void setupCommandLineOptions() { options.addOption(O_CT, "compressionThreshold", true, "Compression threshold; default 4KB"); options.addOption(SoapCLI.OPT_AUTHTOKEN); options.addOption(SoapCLI.OPT_AUTHTOKENFILE); + options.addOption(new Option(O_ST, A_STORE_TYPE, true, H_STORE_TYPE)); + options.addOption(new Option(O_VP, A_VOLUME_PREFIX, true, H_VOLUME_PREFIX)); + options.addOption(new Option(O_STP, A_STORAGE_TYPE, true, H_STORAGE_TYPE)); + options.addOption(new Option(O_BID, A_BUCKET_ID, true, H_BUCKET_ID)); } @Override @@ -417,6 +426,7 @@ protected void usage(ParseException e) { System.err.println(getCommandUsage()); printOpt(O_A, 0); printOpt(O_N, 2); + System.err.println(HELP_EXTERNAL_NAME); printOpt(O_T, 2); printOpt(O_P, 2); printOpt(O_C, 2); @@ -436,6 +446,10 @@ protected void usage(ParseException e) { printOpt(O_TS, 0); printOpt(SoapCLI.O_AUTHTOKEN, 0); printOpt(SoapCLI.O_AUTHTOKENFILE, 0); + printOpt(O_ST, 0); + printOpt(O_VP, 0); + printOpt(O_STP, 0); + printOpt(O_BID, 0); } private void printOpt(String optStr, int leftPad) { @@ -482,4 +496,4 @@ private String toTypeName(short type) { } return "Unrecognized type " + type; } -} +} \ No newline at end of file