Skip to content

Commit 90baae3

Browse files
utils: fix RBD URI if credentials contains slash (#7708)
1 parent f057f4b commit 90baae3

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

ui/src/views/infra/AddPrimaryStorage.vue

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -586,11 +586,6 @@ export default {
586586
},
587587
rbdURL (monitor, pool, id, secret) {
588588
var url
589-
/* Replace the + and / symbols by - and _ to have URL-safe base64 going to the API
590-
It's hacky, but otherwise we'll confuse java.net.URI which splits the incoming URI
591-
*/
592-
secret = secret.replace(/\+/g, '-')
593-
secret = secret.replace(/\//g, '_')
594589
if (id !== null && secret !== null) {
595590
monitor = id + ':' + secret + '@' + monitor
596591
}

utils/src/main/java/com/cloud/utils/UriUtils.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -619,21 +619,30 @@ public static UriInfo getUriInfo(String url) {
619619
}
620620

621621
private static UriInfo getRbdUrlInfo(String url) {
622-
int secondSlash = StringUtils.ordinalIndexOf(url, "/", 2);
623-
int thirdSlash = StringUtils.ordinalIndexOf(url, "/", 3);
622+
if (url == null || !url.toLowerCase().startsWith("rbd://")) {
623+
throw new CloudRuntimeException("RBD URL must start with \"rbd://\"");
624+
}
625+
String schema = StringUtils.substring(url, 0, 6);
626+
url = StringUtils.substring(url, 6, url.length());
624627
int firstAt = StringUtils.indexOf(url, "@");
625-
int lastColon = StringUtils.lastIndexOf(url,":");
626-
int lastSquareBracket = StringUtils.lastIndexOf(url,"]");
627-
int startOfHost = Math.max(secondSlash, firstAt) + 1;
628-
int endOfHost = lastColon < startOfHost ? (thirdSlash > 0 ? thirdSlash : url.length() + 1) :
628+
String credentials = (firstAt == -1) ? null : StringUtils.substring(url, 0, firstAt);
629+
String hostInfo = (firstAt == -1) ? url : StringUtils.substring(url, firstAt + 1, url.length());
630+
631+
int firstSlash = StringUtils.indexOf(hostInfo, "/");
632+
int lastColon = StringUtils.lastIndexOf(hostInfo,":");
633+
int lastSquareBracket = StringUtils.lastIndexOf(hostInfo,"]");
634+
int endOfHost = lastColon == -1 ? (firstSlash > 0 ? firstSlash : hostInfo.length() + 1) :
629635
(lastSquareBracket > lastColon ? lastSquareBracket + 1 : lastColon);
630-
String storageHosts = StringUtils.substring(url, startOfHost, endOfHost);
636+
String storageHosts = StringUtils.substring(hostInfo, 0, endOfHost);
631637
String firstHost = storageHosts.split(",")[0];
632-
String strBeforeHosts = StringUtils.substring(url, 0, startOfHost);
633-
String strAfterHosts = StringUtils.substring(url, endOfHost);
638+
String strAfterHosts = StringUtils.substring(hostInfo, endOfHost);
634639
try {
635-
URI uri = new URI(UriUtils.encodeURIComponent(strBeforeHosts + firstHost + strAfterHosts));
636-
return new UriInfo(uri.getScheme(), storageHosts, uri.getPath(), uri.getUserInfo(), uri.getPort());
640+
URI uri = new URI(UriUtils.encodeURIComponent(schema + firstHost + strAfterHosts));
641+
if (credentials != null) {
642+
credentials = credentials.replace("+", "-");
643+
credentials = credentials.replace("/", "_");
644+
}
645+
return new UriInfo(uri.getScheme(), storageHosts, uri.getPath(), credentials, uri.getPort());
637646
} catch (URISyntaxException e) {
638647
throw new CloudRuntimeException(url + " is not a valid uri for RBD");
639648
}

utils/src/test/java/com/cloud/utils/UriUtilsTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,14 @@ public void testVlanUriNoOverlap() {
103103
}
104104

105105
private void testGetUriInfoInternal(String url, String host) {
106+
testGetUriInfoInternal(url, host, url);
107+
}
108+
109+
private void testGetUriInfoInternal(String url, String host, String newUrl) {
106110
UriUtils.UriInfo uriInfo = UriUtils.getUriInfo(url);
107111

108112
Assert.assertEquals(host, uriInfo.getStorageHost());
109-
Assert.assertEquals(url, uriInfo.toString());
113+
Assert.assertEquals(newUrl, uriInfo.toString());
110114
}
111115

112116
@Test
@@ -122,6 +126,10 @@ public void testGetRbdUriInfo() {
122126
String url6 = String.format("rbd://%s:3300", host);
123127
String url7 = String.format("rbd://%s", host);
124128
String url8 = String.format("rbd://user@%s", host);
129+
String url9 = String.format("rbd://cloudstack:AQD+hJxklW1RGRAAA56oHGN6d+WPDLss2b05Cw==@%s:3300/cloudstack", host);
130+
String url10 = String.format("rbd://cloudstack:AQDlhZxkgdmiKRAA8uHt/O9jqoBp2Iwdk2MjjQ==@%s:3300/cloudstack", host);
131+
String url11 = String.format("rbd://cloudstack:AQD-hJxklW1RGRAAA56oHGN6d-WPDLss2b05Cw==@%s:3300/cloudstack", host);
132+
String url12 = String.format("rbd://cloudstack:AQDlhZxkgdmiKRAA8uHt_O9jqoBp2Iwdk2MjjQ==@%s:3300/cloudstack", host);
125133

126134
testGetUriInfoInternal(url0, host);
127135
testGetUriInfoInternal(url1, host);
@@ -132,6 +140,10 @@ public void testGetRbdUriInfo() {
132140
testGetUriInfoInternal(url6, host);
133141
testGetUriInfoInternal(url7, host);
134142
testGetUriInfoInternal(url8, host);
143+
testGetUriInfoInternal(url9, host, url11);
144+
testGetUriInfoInternal(url10, host, url12);
145+
testGetUriInfoInternal(url11, host);
146+
testGetUriInfoInternal(url12, host);
135147
}
136148

137149
@Test

0 commit comments

Comments
 (0)