diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index f3fb879cbe0..77d2fabdff1 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -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"; diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index acb1423600a..cd8379b9f69 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -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"; diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 60258a0284a..773c0359438 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -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 diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml index ae9708cba98..11732ab46cb 100755 --- a/plugins/hypervisors/ucs/pom.xml +++ b/plugins/hypervisors/ucs/pom.xml @@ -1,16 +1,25 @@ - - + + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 org.apache.cloudstack @@ -18,13 +27,21 @@ 4.3.0-SNAPSHOT ../../pom.xml + org.apache.cloudstack cloud-plugin-hypervisor-ucs + 4.3.0-SNAPSHOT Apache CloudStack Plugin - Hypervisor UCS http://maven.apache.org UTF-8 + + junit + junit + 3.8.1 + test + org.apache.cloudstack cloud-utils @@ -35,5 +52,10 @@ cloud-api ${project.version} + + javax.inject + javax.inject + 1 + diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeDaoImpl.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeDaoImpl.java index 5dc6f79bf7d..98531946862 100644 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeDaoImpl.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeDaoImpl.java @@ -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 }) diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDao.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDao.java index b341a1b2279..9ae4e771283 100644 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDao.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDao.java @@ -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 { } diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDaoImpl.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDaoImpl.java index 9500886875f..30919784adf 100644 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDaoImpl.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDaoImpl.java @@ -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; diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java index c0753f463cd..82328446614 100644 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java @@ -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(); + } } diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java index 945d921a8d3..1eb422c3239 100644 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java @@ -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 req = new HttpEntity(body, requestHeaders); + if (!body.contains("aaaLogin")) { + logger.debug(String.format("UCS call: %s", body)); + } + ResponseEntity 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(); } + */ } } diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java index 0833e31f0f3..0cd695c485e 100755 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java @@ -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 listUcsProfiles(ListUcsProfileCmd cmd); + ListResponse listUcsTemplates(ListUcsTemplatesCmd cmd); + ListResponse listUcsManager(ListUcsManagerCmd cmd); UcsBladeResponse associateProfileToBlade(AssociateUcsProfileToBladeCmd cmd); + UcsBladeResponse instantiateTemplateAndAssociateToBlade(InstantiateUcsTemplateAndAssociateToBladeCmd cmd); + ListResponse listUcsBlades(ListUcsBladeCmd cmd); void deleteUcsManager(Long id); + + ListResponse refreshBlades(Long mgrId); + + UcsBladeResponse disassociateProfile(DisassociateUcsProfileCmd cmd); } diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java index 4239482d1cb..7c9aff06064 100755 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java @@ -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 previous, Map now, UcsManagerVO mgr) { @@ -132,9 +117,9 @@ public class UcsManagerImpl implements UcsManager { } private void syncBlades(UcsManagerVO mgr) { - QueryBuilder q = QueryBuilder.create(UcsBladeVO.class); - q.and(q.entity().getUcsManagerId(), Op.EQ, mgr.getId()); - List pblades = q.list(); + SearchCriteria q = bladeDao.createSearchCriteria(); + q.addAnd("ucsManagerId", Op.EQ, mgr.getId()); + List 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 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 q = QueryBuilder.create(UcsManagerVO.class); - q.and(q.entity().getUrl(), Op.EQ, cmd.getUrl()); - UcsManagerVO mgrvo = q.find(); + SearchCriteria 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 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 tmps = UcsTemplate.fromXmlString(res); + return tmps; + } + private List 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 profiles = UcsProfile.fromXmlString(res); - return profiles; + List tmps = UcsTemplate.fromXmlString(res); + return null; } @Override @@ -311,6 +309,21 @@ public class UcsManagerImpl implements UcsManager { return response; } + @Override + public ListResponse listUcsTemplates(ListUcsTemplatesCmd cmd) { + List templates = getUcsTemplates(cmd.getUcsManagerId()); + ListResponse response = new ListResponse(); + List rs = new ArrayList(); + 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 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 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 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 serv = QueryBuilder.create(UcsManagerVO.class); - serv.and(serv.entity().getZoneId(), Op.EQ, cmd.getZoneId()); - List vos = serv.list(); + + SearchCriteria sc = ucsDao.createSearchCriteria(); + sc.addAnd("zoneId", Op.EQ, cmd.getZoneId()); + List 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 listUcsBlades(ListUcsBladeCmd cmd) { - QueryBuilder serv = QueryBuilder.create(UcsBladeVO.class); - serv.and(serv.entity().getUcsManagerId(), Op.EQ, cmd.getUcsManagerId()); - List vos = serv.list(); - + + private ListResponse listUcsBlades(long mgrId) { + SearchCriteria sc = bladeDao.createSearchCriteria(); + sc.addAnd("ucsManagerId", Op.EQ, mgrId); + List vos = bladeDao.search(sc, null); + List rsps = new ArrayList(vos.size()); for (UcsBladeVO vo : vos) { UcsBladeResponse rsp = bladeVOToResponse(vo); rsps.add(rsp); } - + ListResponse response = new ListResponse(); response.setResponses(rsps); return response; } + @Override + public ListResponse 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 serv = QueryBuilder.create(UcsBladeVO.class); - serv.and(serv.entity().getUcsManagerId(), Op.EQ, id); - List vos = serv.list(); + SearchCriteria sc = bladeDao.createSearchCriteria(); + sc.addAnd("ucsManagerId", Op.EQ, id); + List vos = bladeDao.search(sc, null); for (UcsBladeVO vo : vos) { bladeDao.remove(vo.getId()); } ucsDao.remove(id); } + + @Override + @DB + public ListResponse refreshBlades(Long mgrId) { + SyncBladesThread synct = new SyncBladesThread(); + synct.run(); + + UcsManagerVO mgrvo = ucsDao.findById(mgrId); + List blades = listBlades(mgrvo.getId()); + for (ComputeBlade b : blades) { + SearchCriteria 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; + } }