add os-hypervisors extension for openstack-nova

This commit is contained in:
Arvind Nadendla 2015-07-17 19:38:11 -07:00 committed by Zack Shoylev
parent 1863f859f5
commit 48c0794b09
13 changed files with 547 additions and 19 deletions

View File

@ -124,6 +124,11 @@
<artifactId>auto-service</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>

View File

@ -16,9 +16,8 @@
*/
package org.jclouds.openstack.nova.v2_0;
import java.io.Closeable;
import java.util.Set;
import com.google.common.base.Optional;
import com.google.inject.Provides;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpoint;
import org.jclouds.openstack.nova.v2_0.extensions.AttachInterfaceApi;
@ -29,6 +28,7 @@ import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPPoolApi;
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationApi;
import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi;
import org.jclouds.openstack.nova.v2_0.extensions.HypervisorApi;
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
import org.jclouds.openstack.nova.v2_0.extensions.QuotaApi;
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
@ -46,8 +46,8 @@ import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import com.google.common.base.Optional;
import com.google.inject.Provides;
import java.io.Closeable;
import java.util.Set;
/**
* Provides access to the OpenStack Compute (Nova) v2 API.
@ -219,6 +219,17 @@ public interface NovaApi extends Closeable {
Optional<QuotaApi> getQuotaApi(
@EndpointParam(parser = RegionToEndpoint.class) String region);
/**
* Provides access to Hypervisor features.
*
* <h3>NOTE</h3>
* This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
* to determine if it is present.
*/
@Delegate
Optional<HypervisorApi> getHypervisorApi(
@EndpointParam(parser = RegionToEndpoint.class) String region);
/**
* Provides access to Volume features.
*

View File

@ -16,15 +16,11 @@
*/
package org.jclouds.openstack.nova.v2_0.config;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneHttpApiModule.aliasBinder;
import java.net.URI;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.inject.Provider;
import javax.inject.Singleton;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.inject.Provides;
import com.google.inject.multibindings.MapBinder;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
@ -38,11 +34,13 @@ import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.HttpApiModule;
import org.jclouds.rest.functions.ImplicitOptionalConverter;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.inject.Provides;
import com.google.inject.multibindings.MapBinder;
import javax.inject.Provider;
import javax.inject.Singleton;
import java.net.URI;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneHttpApiModule.aliasBinder;
/**
* Configures the Nova connection.
@ -96,6 +94,8 @@ public class NovaHttpApiModule extends HttpApiModule<NovaApi> {
URI.create("http://docs.openstack.org/compute/ext/os-volume-attachment-update/api/v2"));
aliases.addBinding(URI.create(ExtensionNamespaces.ATTACH_INTERFACES)).toInstance(
URI.create("http://docs.openstack.org/compute/ext/interfaces/api/v1.1"));
aliases.addBinding(URI.create(ExtensionNamespaces.HYPERVISORS)).toInstance(
URI.create("http://docs.openstack.org/compute/ext/hypervisors/api/v1.1"));
}
@Provides

View File

@ -0,0 +1,38 @@
/*
* 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.jclouds.openstack.nova.v2_0.domain.regionscoped;
import com.google.auto.value.AutoValue;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
/**
* Hypervisor which shows id and name
*/
@AutoValue
public abstract class Hypervisor {
public abstract String getId();
@Nullable
public abstract String getName();
@SerializedNames({"id" , "hypervisor_hostname"})
private static Hypervisor create(String id, String name) {
return new AutoValue_Hypervisor(id, name);
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.jclouds.openstack.nova.v2_0.domain.regionscoped;
import com.google.auto.value.AutoValue;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
/**
* Hypervisor which shows id, name and other details
*/
@AutoValue
public abstract class HypervisorDetails {
public abstract String getId();
@Nullable
public abstract String getName();
@Nullable
public abstract Integer getCurrentWorkload();
@Nullable
public abstract Integer getDiskAvailableLeast();
@Nullable
public abstract Integer getFreeDiskGb();
@Nullable
public abstract Integer getFreeRamMb();
public abstract String getHypervisorType();
public abstract int getHypervisorVersion();
public abstract int getLocalGb();
public abstract int getLocalGbUsed();
public abstract int getMemoryMb();
public abstract int getMemoryMbUsed();
@Nullable
public abstract Integer getRunningVms();
public abstract int getVcpus();
public abstract int getVcpusUsed();
@Nullable
public abstract String getCpuInfo();
@SerializedNames({ "id", "hypervisor_hostname", "current_workload", "disk_available_least", "free_disk_gb", "free_ram_mb", "hypervisor_type",
"hypervisor_version", "local_gb", "local_gb_used", "memory_mb", "memory_mb_used", "running_vms", "vcpus", "vcpus_used",
"cpu_info" })
private static HypervisorDetails create(String id, String name, int currentWorkload, int diskAvailableLeast, int freeDiskGb, int freeRamMb,
String hypervisorType, int hypervisorVersion, int localGb, int localGbUsed, int memoryMb, int memoryMbUsed, int runningVms,
int vcpus, int vcpusUsed, String cpuInfo) {
return new AutoValue_HypervisorDetails(id, name, currentWorkload, diskAvailableLeast, freeDiskGb, freeRamMb, hypervisorType, hypervisorVersion,
localGb, localGbUsed, memoryMb, memoryMbUsed, runningVms, vcpus, vcpusUsed, cpuInfo);
}
}

View File

@ -121,6 +121,10 @@ public final class ExtensionNamespaces {
* Attach interfaces extension
*/
public static final String ATTACH_INTERFACES = "http://docs.openstack.org/compute/ext/interfaces/api/v1.1";
/**
* Hypervisor support
*/
public static final String HYPERVISORS = "http://docs.openstack.org/compute/ext/hypervisors/api/v1.1";
private ExtensionNamespaces() {
throw new AssertionError("intentionally unimplemented");

View File

@ -0,0 +1,59 @@
/*
* 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.jclouds.openstack.nova.v2_0.extensions;
import com.google.common.annotations.Beta;
import com.google.common.collect.FluentIterable;
import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.Hypervisor;
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.HypervisorDetails;
import org.jclouds.openstack.v2_0.ServiceType;
import org.jclouds.openstack.v2_0.services.Extension;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
/**
* Provides access to the OpenStack Compute (Nova) Hypervisor Extension API.
*/
@Beta
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.HYPERVISORS)
@RequestFilters(AuthenticateRequest.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/os-hypervisors")
public interface HypervisorApi {
@Named("hypervisors:list")
@GET
@SelectJson("hypervisors")
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
FluentIterable<Hypervisor> list();
@Named("hypervisors:list")
@GET
@Path("/detail")
@SelectJson("hypervisors")
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
FluentIterable<HypervisorDetails> listInDetail();
}

View File

@ -0,0 +1,72 @@
/*
* 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.jclouds.openstack.nova.v2_0.extensions;
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.Hypervisor;
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.HypervisorDetails;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
import org.testng.annotations.Test;
import static org.testng.Assert.assertNotNull;
@Test(groups = "live", testName = "HypervisorApiLiveTest")
public class HypervisorApiLiveTest extends BaseNovaApiLiveTest {
@Test
public void testList() throws Exception {
Optional<? extends HypervisorApi> hypervisorApi = api.getHypervisorApi("RegionOne");
if (hypervisorApi.isPresent()) {
FluentIterable<? extends Hypervisor> hypervisors = hypervisorApi.get().list();
for (Hypervisor hypervisor : hypervisors) {
assertNotNull(hypervisor.getName());
assertNotNull(hypervisor.getId(), "hypervisor: " + hypervisor.getName() + " has invalid id");
}
}
}
@Test
public void testListInDetail() throws Exception {
Optional<? extends HypervisorApi> hypervisorApi = api.getHypervisorApi("RegionOne");
if (hypervisorApi.isPresent()) {
FluentIterable<? extends HypervisorDetails> hypervisors = hypervisorApi.get().listInDetail();
for (HypervisorDetails hypervisorDetails : hypervisors) {
assertNotNull(hypervisorDetails.getId(), "Expected hypervisor id");
assertNotNull(hypervisorDetails.getName(), "Expected hypervisor name");
assertNotNull(hypervisorDetails.getCurrentWorkload(), "Expected CurrentWorkload");
assertNotNull(hypervisorDetails.getDiskAvailableLeast(), "Expected Disk Available Least");
assertNotNull(hypervisorDetails.getFreeDiskGb(), "Expected Free Disk Gb");
assertNotNull(hypervisorDetails.getFreeRamMb(), "Expected Free Ram Mb");
assertNotNull(hypervisorDetails.getHypervisorType(), "Expected Hypervisor Type");
assertNotNull(hypervisorDetails.getHypervisorVersion(), "Expected Hypervisor Version");
assertNotNull(hypervisorDetails.getLocalGb(), "Expected Local Gb");
assertNotNull(hypervisorDetails.getLocalGbUsed(), "Expected Local Gb Used");
assertNotNull(hypervisorDetails.getMemoryMb(), "Expected Memory Mb ");
assertNotNull(hypervisorDetails.getMemoryMbUsed(), "Expected Memory Mb Used");
assertNotNull(hypervisorDetails.getRunningVms(), "Expected Running Vms");
assertNotNull(hypervisorDetails.getVcpus(), "Expected Vcpus");
assertNotNull(hypervisorDetails.getVcpusUsed(), "Expected Vcpus Used");
assertNotNull(hypervisorDetails.getCpuInfo(), "Eexpected Cpu Info");
}
}
}
}

View File

@ -0,0 +1,187 @@
/*
* 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.jclouds.openstack.nova.v2_0.extensions;
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import org.jclouds.openstack.nova.v2_0.NovaApi;
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.Hypervisor;
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.HypervisorDetails;
import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@Test(groups = "unit", testName = "HypervisorApiMockTest")
public class HypervisorApiMockTest extends BaseOpenStackMockTest<NovaApi> {
private static Map<String, MockWebServer> servers = new ConcurrentHashMap<String, MockWebServer>();
@BeforeMethod
public void setupMockServer(Method method) throws IOException {
servers.put(method.getName(), mockOpenStackServer());
servers.get(method.getName()).enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
}
@AfterMethod
public void tearDownMockServer(Method method) throws IOException {
servers.get(method.getName()).shutdown();
}
public void testWhenNamespaceInExtensionsListHypervisorPresent(Method method) throws Exception {
MockWebServer server = servers.get(method.getName());
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/extension_list_full.json"))));
NovaApi novaApi = api(server.getUrl("/").toString(), "openstack-nova");
assertEquals(novaApi.getConfiguredRegions(), ImmutableSet.of("RegionOne", "RegionTwo", "RegionThree"));
Optional<HypervisorApi> hypervisorApi = novaApi.getHypervisorApi("RegionOne");
assertTrue(hypervisorApi.isPresent());
assertRequests(server, 2, null);
}
public void testWhenNamespaceNotInExtensionsListHypervisorPresent(Method method) throws Exception {
MockWebServer server = servers.get(method.getName());
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/extension_list.json"))));
NovaApi novaApi = api(server.getUrl("/").toString(), "openstack-nova");
assertEquals(novaApi.getConfiguredRegions(), ImmutableSet.of("RegionOne", "RegionTwo", "RegionThree"));
Optional<HypervisorApi> hypervisorApi = novaApi.getHypervisorApi("RegionOne");
assertFalse(hypervisorApi.isPresent());
assertRequests(server, 2, null);
}
public void testListHypervisor(Method method) throws Exception {
MockWebServer server = servers.get(method.getName());
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/extension_list_full.json"))));
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/hypervisor_list.json"))));
NovaApi novaApi = api(server.getUrl("/").toString(), "openstack-nova");
assertEquals(novaApi.getConfiguredRegions(), ImmutableSet.of("RegionOne", "RegionTwo", "RegionThree"));
FluentIterable<? extends Hypervisor> hypervisors = novaApi.getHypervisorApi("RegionOne").get().list();
Optional<? extends Hypervisor> hypervisor = hypervisors.first();
assertTrue(hypervisor.isPresent(), "Couldn't find hypervisor");
assertEquals(hypervisor.get().getId(), "1", "Expected hypervisor id to be 1 but it was: " + hypervisor.get().getId());
assertEquals(hypervisor.get().getName(), "os-compute1", "Expected hypervisor name to be os-compute1 but it was: " + hypervisor.get().getName());
assertRequests(server, 3, "/os-hypervisors");
}
public void testListHypervisorWhenResponseIs404(Method method) throws Exception {
MockWebServer server = servers.get(method.getName());
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/extension_list_full.json"))));
server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
NovaApi novaApi = api(server.getUrl("/").toString(), "openstack-nova");
assertEquals(novaApi.getConfiguredRegions(), ImmutableSet.of("RegionOne", "RegionTwo", "RegionThree"));
assertTrue(novaApi.getHypervisorApi("RegionOne").get().list().isEmpty());
assertRequests(server, 3, "/os-hypervisors");
}
public void testListInDetail(Method method) throws Exception {
MockWebServer server = servers.get(method.getName());
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/extension_list_full.json"))));
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/hypervisor_details.json"))));
NovaApi novaApi = api(server.getUrl("/").toString(), "openstack-nova");
assertEquals(novaApi.getConfiguredRegions(), ImmutableSet.of("RegionOne", "RegionTwo", "RegionThree"));
FluentIterable<? extends HypervisorDetails> hypervisors = novaApi.getHypervisorApi("RegionOne").get().listInDetail();
Optional<? extends HypervisorDetails> hypervisorDetailsOptional = hypervisors.first();
assertTrue(hypervisorDetailsOptional.isPresent(), "Couldn't find Hypervisor Details");
HypervisorDetails hypervisorDetails = hypervisorDetailsOptional.get();
assertEquals(hypervisorDetails.getId(), "1", "Expected hypervisor id to be 1 but it was: " + hypervisorDetails.getId());
assertEquals(hypervisorDetails.getName(), "os-compute1",
"Expected hypervisor name to be os-compute1 but it was: " + hypervisorDetails.getName());
assertEquals(hypervisorDetails.getCurrentWorkload(), Integer.valueOf(0),
"Expected CurrentWorkload to be 0 but it was: " + hypervisorDetails.getCurrentWorkload());
assertEquals(hypervisorDetails.getDiskAvailableLeast(), Integer.valueOf(131),
"Expected Disk Available Least to be 131 but it was: " + hypervisorDetails.getDiskAvailableLeast());
assertEquals(hypervisorDetails.getFreeDiskGb(), Integer.valueOf(144),
"Expected Free Disk Gb to be 144 but it was: " + hypervisorDetails.getFreeDiskGb());
assertEquals(hypervisorDetails.getFreeRamMb(), Integer.valueOf(12911),
"Expected Free Ram Mb to be 12911 but it was: " + hypervisorDetails.getFreeRamMb());
assertEquals(hypervisorDetails.getHypervisorType(), "QEMU",
"Expected Hypervisor Type to be QEMU but it was: " + hypervisorDetails.getHypervisorType());
assertEquals(hypervisorDetails.getHypervisorVersion(), 2000000,
"Expected Hypervisor Version to be 2000000 but it was: " + hypervisorDetails.getHypervisorVersion());
assertEquals(hypervisorDetails.getLocalGb(), 195, "Expected Local Gb to be 195 but it was: " + hypervisorDetails.getLocalGb());
assertEquals(hypervisorDetails.getLocalGbUsed(), 51, "Expected Local Gb Used to be 51 but it was: " + hypervisorDetails.getLocalGbUsed());
assertEquals(hypervisorDetails.getMemoryMb(), 20079, "Expected Memory Mb to be 20079 but it was: " + hypervisorDetails.getMemoryMb());
assertEquals(hypervisorDetails.getMemoryMbUsed(), 7168,
"Expected Memory Mb Used to be 7168 but it was: " + hypervisorDetails.getMemoryMbUsed());
assertEquals(hypervisorDetails.getRunningVms(), Integer.valueOf(2),
"Expected Running Vms to be 2 but it was: " + hypervisorDetails.getRunningVms());
assertEquals(hypervisorDetails.getVcpus(), 16, "Expected Vcpus to be 16 but it was: " + hypervisorDetails.getVcpus());
assertEquals(hypervisorDetails.getVcpusUsed(), 5, "Expected Vcpus Used to be 5 but it was: " + hypervisorDetails.getVcpusUsed());
assertEquals(hypervisorDetails.getCpuInfo(),
"{\"vendor\": \"Intel\", \"model\": \"Westmere\", \"arch\": \"x86_64\", \"features\": [\"pge\", \"avx\", \"clflush\", \"sep\", "
+ "\"syscall\", \"vme\", \"tsc\", \"xsave\", \"vmx\", \"cmov\", \"ssse3\", \"pat\", \"lm\", \"msr\", \"nx\", \"fxsr\", \"sse4.1\", "
+ "\"pae\", \"sse4.2\", \"pclmuldq\", \"mmx\", \"osxsave\", \"cx8\", \"mce\", \"de\", \"aes\", \"ht\", \"pse\", \"lahf_lm\","
+ " \"popcnt\", \"mca\", \"apic\", \"sse\", \"ds\", \"pni\", \"rdtscp\", \"sse2\", \"ss\", \"hypervisor\", \"pcid\", \"fpu\","
+ " \"cx16\", \"pse36\", \"mtrr\", \"x2apic\"], \"topology\": {\"cores\": 4, \"threads\": 1, \"sockets\": 1}}",
"Unexpected Cpu Info it was: " + hypervisorDetails.getCpuInfo());
assertRequests(server, 3, "/os-hypervisors/detail");
}
public void testListInDetailWhenResponseIs404(Method method) throws Exception {
MockWebServer server = servers.get(method.getName());
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/extension_list_full.json"))));
server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
NovaApi novaApi = api(server.getUrl("/").toString(), "openstack-nova");
assertEquals(novaApi.getConfiguredRegions(), ImmutableSet.of("RegionOne", "RegionTwo", "RegionThree"));
assertTrue(novaApi.getHypervisorApi("RegionOne").get().listInDetail().isEmpty());
assertRequests(server, 3, "/os-hypervisors/detail");
}
private void assertRequests(MockWebServer server, int requestCount, String requestPath) throws InterruptedException {
assertEquals(server.getRequestCount(), requestCount);
assertAuthentication(server);
assertExtensions(server, "/v2/da0d12be20394afb851716e10a49e4a7");
if (requestPath != null) {
assertRequest(server.takeRequest(), "GET", "/v2/da0d12be20394afb851716e10a49e4a7" + requestPath);
}
}
}

View File

@ -41,6 +41,20 @@
"internalURL": "URL/v2/da0d12be20394afb851716e10a49e4a7",
"region": "RegionOne",
"adminURL": "URL/v2/da0d12be20394afb851716e10a49e4a7"
},
{
"publicURL": "URL/v2/ba0d12be20394afb851716e10a49e4a8",
"id": "2122bcaa704343c19ad2578410d4961d",
"internalURL": "URL/v2/ba0d12be20394afb851716e10a49e4a8",
"region": "RegionTwo",
"adminURL": "URL/v2/ba0d12be20394afb851716e10a49e4a8"
},
{
"publicURL": "URL/v2/ca0d12be20394afb851716e10a49e4a9",
"id": "2122bcaa704343c19ad2578410d4961d",
"internalURL": "URL/v2/ca0d12be20394afb851716e10a49e4a9",
"region": "RegionThree",
"adminURL": "URL/v2/ca0d12be20394afb851716e10a49e4a9"
}
]
},

View File

@ -303,6 +303,14 @@
"namespace": "http://docs.openstack.org/compute/ext/interfaces/api/v1.1",
"alias": "os-attach-interfaces",
"description": "Attach interface support."
},
{
"updated": "2012-06-21T00:00:00Z",
"name": "Hypervisors",
"links": [],
"namespace": "http://docs.openstack.org/compute/ext/hypervisors/api/v1.1",
"alias": "os-hypervisors",
"description": "Admin-only hypervisor administration."
}
]
}

View File

@ -0,0 +1,40 @@
{
"hypervisors": [
{
"vcpus_used": 5,
"hypervisor_type": "QEMU",
"local_gb_used": 51,
"vcpus": 16,
"hypervisor_hostname": "os-compute1",
"memory_mb_used": 7168,
"memory_mb": 20079,
"current_workload": 0,
"cpu_info": "{\"vendor\": \"Intel\", \"model\": \"Westmere\", \"arch\": \"x86_64\", \"features\": [\"pge\", \"avx\", \"clflush\", \"sep\", \"syscall\", \"vme\", \"tsc\", \"xsave\", \"vmx\", \"cmov\", \"ssse3\", \"pat\", \"lm\", \"msr\", \"nx\", \"fxsr\", \"sse4.1\", \"pae\", \"sse4.2\", \"pclmuldq\", \"mmx\", \"osxsave\", \"cx8\", \"mce\", \"de\", \"aes\", \"ht\", \"pse\", \"lahf_lm\", \"popcnt\", \"mca\", \"apic\", \"sse\", \"ds\", \"pni\", \"rdtscp\", \"sse2\", \"ss\", \"hypervisor\", \"pcid\", \"fpu\", \"cx16\", \"pse36\", \"mtrr\", \"x2apic\"], \"topology\": {\"cores\": 4, \"threads\": 1, \"sockets\": 1}}",
"running_vms": 2,
"free_disk_gb": 144,
"hypervisor_version": 2000000,
"disk_available_least": 131,
"local_gb": 195,
"free_ram_mb": 12911,
"id": 1
},
{
"vcpus_used": 8,
"hypervisor_type": "QEMU",
"local_gb_used": 130,
"vcpus": 16,
"hypervisor_hostname": "os-compute02",
"memory_mb_used": 14848,
"memory_mb": 20079,
"current_workload": 0,
"cpu_info": "{\"vendor\": \"Intel\", \"model\": \"Westmere\", \"arch\": \"x86_64\", \"features\": [\"pge\", \"avx\", \"clflush\", \"sep\", \"syscall\", \"vme\", \"tsc\", \"xsave\", \"vmx\", \"cmov\", \"ssse3\", \"pat\", \"lm\", \"msr\", \"nx\", \"fxsr\", \"sse4.1\", \"pae\", \"sse4.2\", \"pclmuldq\", \"mmx\", \"osxsave\", \"cx8\", \"mce\", \"de\", \"aes\", \"ht\", \"pse\", \"lahf_lm\", \"popcnt\", \"mca\", \"apic\", \"sse\", \"ds\", \"pni\", \"rdtscp\", \"sse2\", \"ss\", \"hypervisor\", \"pcid\", \"fpu\", \"cx16\", \"pse36\", \"mtrr\", \"x2apic\"], \"topology\": {\"cores\": 4, \"threads\": 1, \"sockets\": 1}}",
"running_vms": 3,
"free_disk_gb": 65,
"hypervisor_version": 2000000,
"disk_available_least": 38,
"local_gb": 195,
"free_ram_mb": 5231,
"id": 4
}
]
}

View File

@ -0,0 +1,12 @@
{
"hypervisors": [
{
"id": 1,
"hypervisor_hostname": "os-compute1"
},
{
"id": 4,
"hypervisor_hostname": "os-compute02"
}
]
}