Skip to content

Commit 60a1164

Browse files
committed
changes for gzipped userdata check
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 5d993e7 commit 60a1164

File tree

2 files changed

+81
-20
lines changed

2 files changed

+81
-20
lines changed

engine/userdata/cloud-init/src/main/java/org/apache/cloudstack/userdata/CloudInitUserDataProvider.java

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,31 @@
1616
// under the License.
1717
package org.apache.cloudstack.userdata;
1818

19-
import com.cloud.utils.component.AdapterBase;
20-
import com.cloud.utils.exception.CloudRuntimeException;
21-
import org.apache.commons.collections.CollectionUtils;
22-
import org.apache.commons.lang3.StringUtils;
23-
import org.apache.log4j.Logger;
24-
25-
import javax.mail.BodyPart;
26-
import javax.mail.MessagingException;
27-
import javax.mail.Multipart;
28-
import javax.mail.Session;
29-
import javax.mail.internet.MimeBodyPart;
30-
import javax.mail.internet.MimeMessage;
31-
import javax.mail.internet.MimeMultipart;
3219
import java.io.ByteArrayInputStream;
3320
import java.io.ByteArrayOutputStream;
3421
import java.io.IOException;
22+
import java.nio.charset.StandardCharsets;
3523
import java.util.Arrays;
3624
import java.util.List;
3725
import java.util.Map;
3826
import java.util.Properties;
3927
import java.util.stream.Collectors;
28+
import java.util.zip.GZIPInputStream;
29+
30+
import javax.mail.BodyPart;
31+
import javax.mail.MessagingException;
32+
import javax.mail.Multipart;
33+
import javax.mail.Session;
34+
import javax.mail.internet.MimeBodyPart;
35+
import javax.mail.internet.MimeMessage;
36+
import javax.mail.internet.MimeMultipart;
37+
38+
import org.apache.commons.collections.CollectionUtils;
39+
import org.apache.commons.lang3.StringUtils;
40+
import org.apache.log4j.Logger;
41+
42+
import com.cloud.utils.component.AdapterBase;
43+
import com.cloud.utils.exception.CloudRuntimeException;
4044

4145
public class CloudInitUserDataProvider extends AdapterBase implements UserDataProvider {
4246

@@ -65,7 +69,22 @@ public String getName() {
6569
return "cloud-init";
6670
}
6771

72+
protected boolean isGZipped(String userdata) {
73+
if (StringUtils.isEmpty(userdata)) {
74+
return false;
75+
}
76+
byte[] data = userdata.getBytes(StandardCharsets.ISO_8859_1);
77+
if (data.length < 2) {
78+
return false;
79+
}
80+
int magic = data[0] & 0xff | ((data[1] << 8) & 0xff00);
81+
return magic == GZIPInputStream.GZIP_MAGIC;
82+
}
83+
6884
protected String extractUserDataHeader(String userdata) {
85+
if (isGZipped(userdata)) {
86+
throw new CloudRuntimeException("Gzipped user data can not be used together with other user data formats");
87+
}
6988
List<String> lines = Arrays.stream(userdata.split("\n"))
7089
.filter(x -> (x.startsWith("#") && !x.startsWith("##")) || (x.startsWith("Content-Type:")))
7190
.collect(Collectors.toList());

engine/userdata/cloud-init/src/test/java/org/apache/cloudstack/userdata/CloudInitUserDataProviderTest.java

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,28 @@
1616
// under the License.
1717
package org.apache.cloudstack.userdata;
1818

19-
import com.cloud.utils.exception.CloudRuntimeException;
19+
import java.io.ByteArrayOutputStream;
20+
import java.io.IOException;
21+
import java.nio.charset.StandardCharsets;
22+
import java.util.zip.GZIPOutputStream;
23+
2024
import org.junit.Assert;
2125
import org.junit.Test;
2226

27+
import com.cloud.utils.exception.CloudRuntimeException;
28+
2329
public class CloudInitUserDataProviderTest {
2430

2531
private final CloudInitUserDataProvider provider = new CloudInitUserDataProvider();
32+
private final static String CLOUD_CONFIG_USERDATA = "## template: jinja\n" +
33+
"#cloud-config\n" +
34+
"runcmd:\n" +
35+
" - echo 'TestVariable {{ ds.meta_data.variable1 }}' >> /tmp/variable\n" +
36+
" - echo 'Hostname {{ ds.meta_data.public_hostname }}' > /tmp/hostname";
2637

2738
@Test
2839
public void testGetUserDataFormatType() {
29-
String userdata = "## template: jinja\n" +
30-
"#cloud-config\n" +
31-
"runcmd:\n" +
32-
" - echo 'TestVariable {{ ds.meta_data.variable1 }}' >> /tmp/variable\n" +
33-
" - echo 'Hostname {{ ds.meta_data.public_hostname }}' > /tmp/hostname";
34-
CloudInitUserDataProvider.FormatType type = provider.getUserDataFormatType(userdata);
40+
CloudInitUserDataProvider.FormatType type = provider.getUserDataFormatType(CLOUD_CONFIG_USERDATA);
3541
Assert.assertEquals(CloudInitUserDataProvider.FormatType.CLOUD_CONFIG, type);
3642
}
3743

@@ -94,4 +100,40 @@ public void testAppendUserDataInvalidUserData() {
94100
"date > /provisioned";
95101
provider.appendUserData(templateData, vmData);
96102
}
103+
104+
@Test
105+
public void testIsGzippedUserDataWithCloudConfigData() {
106+
Assert.assertFalse(provider.isGZipped(CLOUD_CONFIG_USERDATA));
107+
}
108+
109+
private String createGzipDataAsString() throws IOException {
110+
byte[] input = CLOUD_CONFIG_USERDATA.getBytes(StandardCharsets.ISO_8859_1);
111+
112+
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
113+
GZIPOutputStream outputStream = new GZIPOutputStream(arrayOutputStream);
114+
outputStream.write(input,0, input.length);
115+
outputStream.close();
116+
117+
return arrayOutputStream.toString(StandardCharsets.ISO_8859_1);
118+
}
119+
120+
@Test
121+
public void testIsGzippedUserDataWithValidGzipData() {
122+
try {
123+
String gzipped = createGzipDataAsString();
124+
Assert.assertTrue(provider.isGZipped(gzipped));
125+
} catch (IOException e) {
126+
Assert.fail(e.getMessage());
127+
}
128+
}
129+
130+
@Test(expected = CloudRuntimeException.class)
131+
public void testAppendUserDataWithGzippedData() {
132+
try {
133+
provider.appendUserData(CLOUD_CONFIG_USERDATA, createGzipDataAsString());
134+
Assert.fail("Gzipped data shouldn't be appended with other data");
135+
} catch (IOException e) {
136+
Assert.fail("Exception encountered: " + e.getMessage());
137+
}
138+
}
97139
}

0 commit comments

Comments
 (0)