Author: Frank.Zhang <frank.zhang@citrix.com>
Date:   Thu Oct 10 14:45:03 2013 -0700

    CLOUDSTACK-4850
        [UCS] using template instead of cloning profile
This commit is contained in:
Frank.Zhang 2013-12-05 17:25:57 -08:00
parent 3b59dfebff
commit ef6038f1b3
11 changed files with 396 additions and 128 deletions

View File

@ -452,6 +452,9 @@ public class EventTypes {
public static final String EVENT_CLEANUP_VM_RESERVATION = "VM.RESERVATION.CLEANUP";
public static final String EVENT_UCS_ASSOCIATED_PROFILE = "UCS.ASSOCIATEPROFILE";
public static final String EVENT_UCS_INSTANTIATE_TEMPLATE_AND_ASSOCIATE = "UCS.TEMPLATEASSOCIATION";
public static final String EVENT_UCS_DISASSOCIATED_PROFILE = "UCS.DISASSOCIATEPROFILE";
public static final String EVENT_UCS_REFRESH_BLADES = "UCS.REFRESHBLADES";
// Object store migration
public static final String EVENT_MIGRATE_PREPARE_SECONDARY_STORAGE = "MIGRATE.PREPARE.SS";

View File

@ -506,8 +506,11 @@ public class ApiConstants {
public static final String RESERVED_IP_RANGE = "reservediprange";
public static final String UCS_MANAGER_ID = "ucsmanagerid";
public static final String UCS_PROFILE_DN = "profiledn";
public static final String UCS_TEMPLATE_DN = "templatedn";
public static final String UCS_BLADE_DN = "bladedn";
public static final String UCS_BLADE_ID = "bladeid";
public static final String UCS_PROFILE_NAME = "profilename";
public static final String UCS_DELETE_PROFILE = "deleteprofile";
public static final String VM_GUEST_IP = "vmguestip";
public static final String HEALTHCHECK_RESPONSE_TIMEOUT = "responsetimeout";
public static final String HEALTHCHECK_INTERVAL_TIME = "intervaltime";

View File

@ -637,8 +637,12 @@ addUcsManager=1
listUcsManagers=1
listUcsProfiles=1
listUcsBlades=1
listUcsTemplates=1
associateUcsProfileToBlade=1
deleteUcsManager=1
disassociateUcsProfileFromBlade=1
refreshUcsBlades=1
instantiateUcsTemplateAndAssocaciateToBlade=1
#### New Load Balancer commands
createLoadBalancer=15

View File

@ -1,16 +1,25 @@
<!-- 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. -->
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
<!--
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.
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.cloudstack</groupId>
@ -18,13 +27,21 @@
<version>4.3.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hypervisor-ucs</artifactId>
<version>4.3.0-SNAPSHOT</version>
<name>Apache CloudStack Plugin - Hypervisor UCS</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId>
@ -35,5 +52,10 @@
<artifactId>cloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</dependencies>
</project>

View File

@ -19,6 +19,8 @@ package com.cloud.ucs.database;
import javax.ejb.Local;
import org.springframework.stereotype.Component;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
@Local(value = { UcsBladeDao.class })

View File

@ -27,7 +27,6 @@ import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.GenericQueryBuilder;
public interface UcsManagerDao extends GenericDao<UcsManagerVO, Long> {
}

View File

@ -19,6 +19,8 @@ package com.cloud.ucs.database;
import javax.ejb.Local;
import org.springframework.stereotype.Component;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;

View File

@ -50,6 +50,27 @@ public class UcsCommands {
return cmd.dump();
}
public static String listTemplates(String cookie) {
XmlObject cmd = new XmlObject("configResolveClass");
cmd.putElement("cookie", cookie);
cmd.putElement("inHierarchical", "false");
cmd.putElement("classId", "lsServer");
cmd.putElement("inFilter", new XmlObject("inFilter")
.putElement("eq", new XmlObject("eq")
.putElement("class", "lsServer").putElement("property", "type").putElement("value", "initial-template")));
return cmd.dump();
}
public static String instantiateTemplate(String cookie, String dn, String name) {
XmlObject cmd = new XmlObject("lsInstantiateTemplate");
cmd.putElement("dn",dn);
cmd.putElement("cookie", cookie);
cmd.putElement("inTargetOrg", "org-root");
cmd.putElement("inServerName", name);
cmd.putElement("inHierarchical", "no");
return cmd.toString();
}
public static String cloneProfile(String cookie, String srcDn, String newProfileName) {
XmlObject cmd = new XmlObject("lsClone");
cmd.putElement("cookie", cookie);
@ -67,42 +88,65 @@ public class UcsCommands {
return cmd.toString();
}
public static String associateProfileToBlade(String cookie, String profileDn, String bladeDn) {
XmlObject cmd = new XmlObject("configConfMos").putElement("cookie", cookie).putElement("inHierarchical", "true").putElement(
"inConfigs", new XmlObject("inConfigs").putElement(
"pair", new XmlObject("pair").putElement("key", profileDn).putElement(
"lsServer", new XmlObject("lsServer")
.putElement("agentPolicyName", "")
.putElement("biosProfileName", "")
.putElement("bootPolicyName", "")
.putElement("descr", "")
.putElement("dn", profileDn)
.putElement("dynamicConPolicyName", "")
.putElement("extIPState", "none")
.putElement("hostFwPolicyName", "")
.putElement("identPoolName", "")
.putElement("localDiskPolicyName", "")
.putElement("maintPolicyName", "")
.putElement("mgmtAccessPolicyName", "")
.putElement("mgmtFwPolicyName", "")
.putElement("powerPolicyName", "")
.putElement("scrubPolicyName", "")
.putElement("solPolicyName", "")
.putElement("srcTemplName", "")
.putElement("statsPolicyName", "default")
.putElement("status", "")
.putElement("usrLbl", "")
.putElement("uuid", "")
.putElement("vconProfileName", "")
.putElement("lsBinding", new XmlObject("lsBinding")
.putElement("pnDn", bladeDn)
.putElement("restrictMigration", "no")
.putElement("rn", "pn")
)
)
public static String disassociateProfileFromBlade(String cookie, String profileDn) {
XmlObject cmd = new XmlObject("configConfMo");
cmd.putElement("cookie", cookie);
cmd.putElement("inHierarchical", "false")
.putElement("inConfig", new XmlObject("inConfig")
.putElement("lsServer", new XmlObject("lsServer")
.putElement("dn", profileDn).putElement("lsBinding", new XmlObject("lsBinding").putElement("rn", "pn").putElement("status", "deleted"))
)
);
return cmd.dump();
}
public static String deleteProfile(String cookie, String profileDn) {
XmlObject cmd = new XmlObject("configConfMos");
cmd.putElement("cookie", cookie);
cmd.putElement("inHierarchical", "true")
.putElement("inConfigs", new XmlObject("inConfigs").putElement("pair", new XmlObject("pair").putElement("key", profileDn)
.putElement("lsServer", new XmlObject("lsServer").putElement("dn", profileDn).putElement("status", "deleted"))
));
return cmd.dump();
}
public static String associateProfileToBlade(String cookie, String profileDn, String bladeDn) {
XmlObject cmd = new XmlObject("configConfMos").putElement("cookie", cookie).putElement("inHierarchical", "true").putElement(
"inConfigs", new XmlObject("inConfigs").putElement(
"pair", new XmlObject("pair").putElement("key", profileDn).putElement(
"lsServer", new XmlObject("lsServer")
.putElement("agentPolicyName", "")
.putElement("biosProfileName", "")
.putElement("bootPolicyName", "")
.putElement("descr", "")
.putElement("dn", profileDn)
.putElement("dynamicConPolicyName", "")
.putElement("extIPState", "none")
.putElement("hostFwPolicyName", "")
.putElement("identPoolName", "")
.putElement("localDiskPolicyName", "")
.putElement("maintPolicyName", "")
.putElement("mgmtAccessPolicyName", "")
.putElement("mgmtFwPolicyName", "")
.putElement("powerPolicyName", "")
.putElement("scrubPolicyName", "")
.putElement("solPolicyName", "")
.putElement("srcTemplName", "")
.putElement("statsPolicyName", "default")
.putElement("status", "")
.putElement("usrLbl", "")
.putElement("uuid", "")
.putElement("vconProfileName", "")
.putElement("lsBinding", new XmlObject("lsBinding")
.putElement("pnDn", bladeDn)
.putElement("restrictMigration", "no")
.putElement("rn", "pn")
)
)
)
);
return cmd.dump();
}
}

View File

@ -17,27 +17,76 @@
//
package com.cloud.ucs.manager;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.protocol.Protocol;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.log4j.Logger;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.net.URISyntaxException;
public class UcsHttpClient {
private static HttpClient client = new HttpClient();
private static final Logger logger = Logger.getLogger(UcsHttpClient.class);
//private static HttpClient client;
private static Protocol ucsHttpsProtocol = new org.apache.commons.httpclient.protocol.Protocol("https", new EasySSLProtocolSocketFactory(), 443);
private final String url;
private static RestTemplate template;
static {
//client = new HttpClient();
template = new RestTemplate();
}
public UcsHttpClient(String ip) {
url = String.format("http://%s/nuova", ip);
Protocol.registerProtocol("https", ucsHttpsProtocol);
}
public String call(String xml) {
private String call(URI uri, String body) {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_XML);
requestHeaders.setContentLength(body.length());
HttpEntity<String> req = new HttpEntity<String>(body, requestHeaders);
if (!body.contains("aaaLogin")) {
logger.debug(String.format("UCS call: %s", body));
}
ResponseEntity<String> rsp = template.exchange(uri, HttpMethod.POST, req, String.class);
if (rsp.getStatusCode() == org.springframework.http.HttpStatus.OK) {
return rsp.getBody();
} else if (rsp.getStatusCode() == org.springframework.http.HttpStatus.FOUND) {
// Handle HTTPS redirect
// Ideal way might be to configure from add manager API
// for using either HTTP / HTTPS
// Allow only one level of redirect
java.net.URI location = rsp.getHeaders().getLocation();
if (location == null) {
throw new CloudRuntimeException("Call failed: Bad redirect from UCS Manager");
}
//call(location, body);
rsp = template.exchange(location, HttpMethod.POST, req, String.class);
}
if (rsp.getStatusCode() != org.springframework.http.HttpStatus.OK) {
String err = String.format("http status: %s, response body:%s", rsp.getStatusCode().toString(), rsp.getBody());
throw new CloudRuntimeException(String.format("UCS API call failed, details: %s\n", err));
}
if (rsp.getBody().contains("errorCode")) {
String err = String.format("ucs call failed:\nsubmitted doc:%s\nresponse:%s\n", body, rsp.getBody());
throw new CloudRuntimeException(err);
}
return rsp.getBody();
}
public String call(String body) {
try {
return call(new URI(url), body);
} catch (URISyntaxException e) {
throw new CloudRuntimeException(e);
}
/*
PostMethod post = new PostMethod(url);
post.setRequestEntity(new StringRequestEntity(xml));
post.setRequestHeader("Content-type", "text/xml");
@ -75,5 +124,6 @@ public class UcsHttpClient {
} finally {
post.releaseConnection();
}
*/
}
}

View File

@ -17,15 +17,8 @@
//
package com.cloud.ucs.manager;
import org.apache.cloudstack.api.AddUcsManagerCmd;
import org.apache.cloudstack.api.AssociateUcsProfileToBladeCmd;
import org.apache.cloudstack.api.ListUcsBladeCmd;
import org.apache.cloudstack.api.ListUcsManagerCmd;
import org.apache.cloudstack.api.ListUcsProfileCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.UcsBladeResponse;
import org.apache.cloudstack.api.response.UcsManagerResponse;
import org.apache.cloudstack.api.response.UcsProfileResponse;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.*;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.PluggableService;
@ -35,11 +28,19 @@ public interface UcsManager extends Manager, PluggableService {
ListResponse<UcsProfileResponse> listUcsProfiles(ListUcsProfileCmd cmd);
ListResponse<UcsTemplateResponse> listUcsTemplates(ListUcsTemplatesCmd cmd);
ListResponse<UcsManagerResponse> listUcsManager(ListUcsManagerCmd cmd);
UcsBladeResponse associateProfileToBlade(AssociateUcsProfileToBladeCmd cmd);
UcsBladeResponse instantiateTemplateAndAssociateToBlade(InstantiateUcsTemplateAndAssociateToBladeCmd cmd);
ListResponse<UcsBladeResponse> listUcsBlades(ListUcsBladeCmd cmd);
void deleteUcsManager(Long id);
ListResponse<UcsBladeResponse> refreshBlades(Long mgrId);
UcsBladeResponse disassociateProfile(DisassociateUcsProfileCmd cmd);
}

View File

@ -17,33 +17,6 @@
//
package com.cloud.ucs.manager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.AddUcsManagerCmd;
import org.apache.cloudstack.api.AssociateUcsProfileToBladeCmd;
import org.apache.cloudstack.api.DeleteUcsManagerCmd;
import org.apache.cloudstack.api.ListUcsBladeCmd;
import org.apache.cloudstack.api.ListUcsManagerCmd;
import org.apache.cloudstack.api.ListUcsProfileCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.UcsBladeResponse;
import org.apache.cloudstack.api.response.UcsManagerResponse;
import org.apache.cloudstack.api.response.UcsProfileResponse;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import com.cloud.configuration.Config;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.DataCenterVO;
@ -59,14 +32,26 @@ import com.cloud.ucs.database.UcsManagerVO;
import com.cloud.ucs.structure.ComputeBlade;
import com.cloud.ucs.structure.UcsCookie;
import com.cloud.ucs.structure.UcsProfile;
import com.cloud.ucs.structure.UcsTemplate;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.xmlobject.XmlObject;
import com.cloud.utils.xmlobject.XmlObjectParser;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.*;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Local(value = { UcsManager.class })
public class UcsManagerImpl implements UcsManager {
@ -98,7 +83,7 @@ public class UcsManagerImpl implements UcsManager {
private ScheduledExecutorService syncBladesExecutor;
private int syncBladeInterval;
private class SyncBladesThread extends ManagedContextRunnable {
private class SyncBladesThread implements Runnable {
private void discoverNewBlades(Map<String, UcsBladeVO> previous,
Map<String, ComputeBlade> now, UcsManagerVO mgr) {
@ -132,9 +117,9 @@ public class UcsManagerImpl implements UcsManager {
}
private void syncBlades(UcsManagerVO mgr) {
QueryBuilder<UcsBladeVO> q = QueryBuilder.create(UcsBladeVO.class);
q.and(q.entity().getUcsManagerId(), Op.EQ, mgr.getId());
List<UcsBladeVO> pblades = q.list();
SearchCriteria<UcsBladeVO> q = bladeDao.createSearchCriteria();
q.addAnd("ucsManagerId", Op.EQ, mgr.getId());
List<UcsBladeVO> pblades = bladeDao.search(q, null);
if (pblades.isEmpty()) {
return;
}
@ -156,7 +141,7 @@ public class UcsManagerImpl implements UcsManager {
}
@Override
protected void runInContext() {
public void run() {
try {
List<UcsManagerVO> mgrs = ucsDao.listAll();
for (UcsManagerVO mgr : mgrs) {
@ -203,6 +188,9 @@ public class UcsManagerImpl implements UcsManager {
vo.setDn(b.getDn());
vo.setUcsManagerId(ucsMgrVo.getId());
vo.setUuid(UUID.randomUUID().toString());
if (!"".equals(b.getAssignedToDn())) {
vo.setProfileDn(b.getAssignedToDn());
}
bladeDao.persist(vo);
}
}
@ -210,9 +198,9 @@ public class UcsManagerImpl implements UcsManager {
@Override
@DB
public UcsManagerResponse addUcsManager(AddUcsManagerCmd cmd) {
QueryBuilder<UcsManagerVO> q = QueryBuilder.create(UcsManagerVO.class);
q.and(q.entity().getUrl(), Op.EQ, cmd.getUrl());
UcsManagerVO mgrvo = q.find();
SearchCriteria<UcsManagerVO> q = ucsDao.createSearchCriteria();
q.addAnd("url", Op.EQ, cmd.getUrl());
UcsManagerVO mgrvo = ucsDao.findOneBy(q);
if (mgrvo != null) {
throw new IllegalArgumentException(String.format("duplicate UCS manager. url[%s] is used by another UCS manager already", cmd.getUrl()));
}
@ -263,7 +251,7 @@ public class UcsManagerImpl implements UcsManager {
cmd = UcsCommands.refreshCmd(mgrvo.getUsername(), mgrvo.getPassword(), cookie);
}
}
if(!(cmd == null)) {
if(cmd != null) {
String ret = client.call(cmd);
XmlObject xo = XmlObjectParser.parseFromString(ret);
String cookie = xo.get("outCookie");
@ -286,14 +274,24 @@ public class UcsManagerImpl implements UcsManager {
return ComputeBlade.fromXmString(ret);
}
private List<UcsTemplate> getUcsTemplates(Long ucsMgrId) {
String cookie = getCookie(ucsMgrId);
UcsManagerVO mgrvo = ucsDao.findById(ucsMgrId);
String cmd = UcsCommands.listTemplates(cookie);
UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
String res = client.call(cmd);
List<UcsTemplate> tmps = UcsTemplate.fromXmlString(res);
return tmps;
}
private List<UcsProfile> getUcsProfiles(Long ucsMgrId) {
String cookie = getCookie(ucsMgrId);
UcsManagerVO mgrvo = ucsDao.findById(ucsMgrId);
String cmd = UcsCommands.listProfiles(cookie);
String cmd = UcsCommands.listTemplates(cookie);
UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
String res = client.call(cmd);
List<UcsProfile> profiles = UcsProfile.fromXmlString(res);
return profiles;
List<UcsTemplate> tmps = UcsTemplate.fromXmlString(res);
return null;
}
@Override
@ -311,6 +309,21 @@ public class UcsManagerImpl implements UcsManager {
return response;
}
@Override
public ListResponse<UcsTemplateResponse> listUcsTemplates(ListUcsTemplatesCmd cmd) {
List<UcsTemplate> templates = getUcsTemplates(cmd.getUcsManagerId());
ListResponse<UcsTemplateResponse> response = new ListResponse<UcsTemplateResponse>();
List<UcsTemplateResponse> rs = new ArrayList<UcsTemplateResponse>();
for (UcsTemplate t : templates) {
UcsTemplateResponse r = new UcsTemplateResponse();
r.setObjectName("ucstemplate");
r.setDn(t.getDn());
rs.add(r);
}
response.setResponses(rs);
return response;
}
private String cloneProfile(Long ucsMgrId, String srcDn, String newProfileName) {
UcsManagerVO mgrvo = ucsDao.findById(ucsMgrId);
UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
@ -321,6 +334,7 @@ public class UcsManagerImpl implements UcsManager {
return xo.get("outConfig.lsServer.dn");
}
private boolean isProfileAssociated(Long ucsMgrId, String dn) {
UcsManagerVO mgrvo = ucsDao.findById(ucsMgrId);
UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
@ -328,21 +342,33 @@ public class UcsManagerImpl implements UcsManager {
String cmd = UcsCommands.configResolveDn(cookie, dn);
String res = client.call(cmd);
XmlObject xo = XmlObjectParser.parseFromString(res);
return xo.get("outConfig.lsServer.assocState").equals("associated");
}
private boolean isBladeAssociated(Long ucsMgrId, String dn) {
UcsManagerVO mgrvo = ucsDao.findById(ucsMgrId);
UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
String cookie = getCookie(ucsMgrId);
String cmd = UcsCommands.configResolveDn(cookie, dn);
String res = client.call(cmd);
XmlObject xo = XmlObjectParser.parseFromString(res);
s_logger.debug(String.format("association response is %s", res));
if (xo.get("outConfig.computeBlade.association").equals("none")) {
throw new CloudRuntimeException(String.format("cannot associated a profile to blade[dn:%s]. please check your UCS manasger for detailed error information", dn));
}
return xo.get("outConfig.computeBlade.association").equals("associated");
//return !xo.get("outConfig.computeBlade.assignedToDn").equals("");
}
@Override
public UcsBladeResponse associateProfileToBlade(AssociateUcsProfileToBladeCmd cmd) {
QueryBuilder<UcsBladeVO> q = QueryBuilder.create(UcsBladeVO.class);
q.and(q.entity().getUcsManagerId(), Op.EQ, cmd.getUcsManagerId());
q.and(q.entity().getId(), Op.EQ, cmd.getBladeId());
UcsBladeVO bvo = q.find();
SearchCriteria<UcsBladeVO> sc = bladeDao.createSearchCriteria();
sc.addAnd("ucsManagerId", Op.EQ, cmd.getUcsManagerId());
sc.addAnd("id", Op.EQ, cmd.getBladeId());
UcsBladeVO bvo = bladeDao.findOneBy(sc);
if (bvo == null) {
throw new IllegalArgumentException(String.format("cannot find UCS blade[id:%s, ucs manager id:%s]", cmd.getBladeId(), cmd.getUcsManagerId()));
}
@ -358,9 +384,9 @@ public class UcsManagerImpl implements UcsManager {
UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
String res = client.call(ucscmd);
int count = 0;
int timeout = 600;
int timeout = 3600;
while (count < timeout) {
if (isProfileAssociated(mgrvo.getId(), bvo.getDn())) {
if (isBladeAssociated(mgrvo.getId(), bvo.getDn())) {
break;
}
@ -386,6 +412,63 @@ public class UcsManagerImpl implements UcsManager {
return rsp;
}
@Override
public UcsBladeResponse instantiateTemplateAndAssociateToBlade(InstantiateUcsTemplateAndAssociateToBladeCmd cmd) {
String profileName = cmd.getProfileName();
if (profileName == null || "".equals(profileName)) {
profileName = UUID.randomUUID().toString().replace("-", "");
}
SearchCriteria<UcsBladeVO> sc = bladeDao.createSearchCriteria();
sc.addAnd("ucsManagerId", Op.EQ, cmd.getUcsManagerId());
sc.addAnd("id", Op.EQ, cmd.getBladeId());
UcsBladeVO bvo = bladeDao.findOneBy(sc);
if (bvo == null) {
throw new IllegalArgumentException(String.format("cannot find UCS blade[id:%s, ucs manager id:%s]", cmd.getBladeId(), cmd.getUcsManagerId()));
}
if (bvo.getHostId() != null) {
throw new CloudRuntimeException(String.format("blade[id:%s, dn:%s] has been associated with host[id:%s]", bvo.getId(), bvo.getDn(), bvo.getHostId()));
}
UcsManagerVO mgrvo = ucsDao.findById(cmd.getUcsManagerId());
String cookie = getCookie(cmd.getUcsManagerId());
String instantiateTemplateCmd = UcsCommands.instantiateTemplate(cookie, cmd.getTemplateDn(), profileName);
UcsHttpClient http = new UcsHttpClient(mgrvo.getUrl());
String res = http.call(instantiateTemplateCmd);
XmlObject xo = XmlObjectParser.parseFromString(res);
String profileDn = xo.get("outConfig.lsServer.dn");
String ucscmd = UcsCommands.associateProfileToBlade(cookie, profileDn, bvo.getDn());
res = http.call(ucscmd);
int count = 0;
int timeout = 3600;
while (count < timeout) {
if (isBladeAssociated(mgrvo.getId(), bvo.getDn())) {
break;
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
throw new CloudRuntimeException(e);
}
count += 2;
}
if (count >= timeout) {
throw new CloudRuntimeException(String.format("associating profile[%s] to balde[%s] timeout after 600 seconds", profileDn, bvo.getDn()));
}
bvo.setProfileDn(profileDn);
bladeDao.update(bvo.getId(), bvo);
UcsBladeResponse rsp = bladeVOToResponse(bvo);
s_logger.debug(String.format("successfully associated profile[%s] to blade[%s]", profileDn, bvo.getDn()));
return rsp;
}
private String hostIdToUuid(Long hostId) {
if (hostId == null) {
return null;
@ -420,10 +503,10 @@ public class UcsManagerImpl implements UcsManager {
response.setResponses(rsps);
return response;
}
QueryBuilder<UcsManagerVO> serv = QueryBuilder.create(UcsManagerVO.class);
serv.and(serv.entity().getZoneId(), Op.EQ, cmd.getZoneId());
List<UcsManagerVO> vos = serv.list();
SearchCriteria<UcsManagerVO> sc = ucsDao.createSearchCriteria();
sc.addAnd("zoneId", Op.EQ, cmd.getZoneId());
List<UcsManagerVO> vos = ucsDao.search(sc, null);
for (UcsManagerVO vo : vos) {
UcsManagerResponse rsp = new UcsManagerResponse();
@ -448,25 +531,29 @@ public class UcsManagerImpl implements UcsManager {
rsp.setUcsManagerId(ucsManagerIdToUuid(vo.getUcsManagerId()));
return rsp;
}
@Override
public ListResponse<UcsBladeResponse> listUcsBlades(ListUcsBladeCmd cmd) {
QueryBuilder<UcsBladeVO> serv = QueryBuilder.create(UcsBladeVO.class);
serv.and(serv.entity().getUcsManagerId(), Op.EQ, cmd.getUcsManagerId());
List<UcsBladeVO> vos = serv.list();
private ListResponse<UcsBladeResponse> listUcsBlades(long mgrId) {
SearchCriteria<UcsBladeVO> sc = bladeDao.createSearchCriteria();
sc.addAnd("ucsManagerId", Op.EQ, mgrId);
List<UcsBladeVO> vos = bladeDao.search(sc, null);
List<UcsBladeResponse> rsps = new ArrayList<UcsBladeResponse>(vos.size());
for (UcsBladeVO vo : vos) {
UcsBladeResponse rsp = bladeVOToResponse(vo);
rsps.add(rsp);
}
ListResponse<UcsBladeResponse> response = new ListResponse<UcsBladeResponse>();
response.setResponses(rsps);
return response;
}
@Override
public ListResponse<UcsBladeResponse> listUcsBlades(ListUcsBladeCmd cmd) {
return listUcsBlades(cmd.getUcsManagerId());
}
@Override
public void setName(String name) {
this.name = name;
@ -501,17 +588,68 @@ public class UcsManagerImpl implements UcsManager {
cmds.add(AddUcsManagerCmd.class);
cmds.add(AssociateUcsProfileToBladeCmd.class);
cmds.add(DeleteUcsManagerCmd.class);
cmds.add(DisassociateUcsProfileCmd.class);
cmds.add(RefreshUcsBladesCmd.class);
cmds.add(ListUcsTemplatesCmd.class);
cmds.add(InstantiateUcsTemplateAndAssociateToBladeCmd.class);
return cmds;
}
@Override
public void deleteUcsManager(Long id) {
QueryBuilder<UcsBladeVO> serv = QueryBuilder.create(UcsBladeVO.class);
serv.and(serv.entity().getUcsManagerId(), Op.EQ, id);
List<UcsBladeVO> vos = serv.list();
SearchCriteria<UcsBladeVO> sc = bladeDao.createSearchCriteria();
sc.addAnd("ucsManagerId", Op.EQ, id);
List<UcsBladeVO> vos = bladeDao.search(sc, null);
for (UcsBladeVO vo : vos) {
bladeDao.remove(vo.getId());
}
ucsDao.remove(id);
}
@Override
@DB
public ListResponse<UcsBladeResponse> refreshBlades(Long mgrId) {
SyncBladesThread synct = new SyncBladesThread();
synct.run();
UcsManagerVO mgrvo = ucsDao.findById(mgrId);
List<ComputeBlade> blades = listBlades(mgrvo.getId());
for (ComputeBlade b : blades) {
SearchCriteria<UcsBladeVO> sc = bladeDao.createSearchCriteria();
sc.addAnd("dn", Op.EQ, b.getDn());
UcsBladeVO vo = bladeDao.findOneBy(sc);
if (vo == null) {
vo = new UcsBladeVO();
vo.setProfileDn("".equals(b.getAssignedToDn()) ? null : b.getAssignedToDn());
vo.setDn(b.getDn());
vo.setUuid(UUID.randomUUID().toString());
vo.setUcsManagerId(mgrId);
bladeDao.persist(vo);
} else {
vo.setProfileDn("".equals(b.getAssignedToDn()) ? null : b.getAssignedToDn());
bladeDao.update(vo.getId(), vo);
}
}
return listUcsBlades(mgrId);
}
@Override
public UcsBladeResponse disassociateProfile(DisassociateUcsProfileCmd cmd) {
UcsBladeVO blade = bladeDao.findById(cmd.getBladeId());
UcsManagerVO mgrvo = ucsDao.findById(blade.getUcsManagerId());
UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
String cookie = getCookie(mgrvo.getId());
String call = UcsCommands.disassociateProfileFromBlade(cookie, blade.getProfileDn());
client.call(call);
if (cmd.isDeleteProfile()) {
call = UcsCommands.deleteProfile(cookie, blade.getProfileDn());
client = new UcsHttpClient(mgrvo.getUrl());
client.call(call);
}
blade.setProfileDn(null);
bladeDao.update(blade.getId(), blade);
UcsBladeResponse rsp = bladeVOToResponse(blade);
return rsp;
}
}