/*************************************************************************** * Copyright (c) 2014-2017 VMware, Inc. All Rights Reserved. * Licensed 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 com.vmware.bdd.plugin; import java.io.IOException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Properties; import java.util.zip.ZipException; import org.apache.log4j.Logger; import com.vmware.aurora.global.Configuration; import com.vmware.aurora.security.CmsKeyStore; import com.vmware.aurora.security.JksKeyStoreUtil; import com.vmware.aurora.util.AuAssert; import com.vmware.aurora.vc.vcservice.VcContext; import com.vmware.aurora.vc.vcservice.VcSession; import com.vmware.bdd.utils.CommonUtil; import com.vmware.bdd.utils.Constants; import com.vmware.bdd.utils.ShellCommandExecutor; import com.vmware.vim.binding.impl.vim.DescriptionImpl; import com.vmware.vim.binding.impl.vim.ExtensionImpl; import com.vmware.vim.binding.impl.vim.ExtensionImpl.ClientInfoImpl; import com.vmware.vim.binding.impl.vim.ExtensionImpl.ServerInfoImpl; import com.vmware.vim.binding.vim.Description; import com.vmware.vim.binding.vim.Extension; import com.vmware.vim.binding.vim.Extension.ClientInfo; import com.vmware.vim.binding.vim.Extension.ServerInfo; /** * Register the ngc plugin as an extension service to the VC the oms server is * deployed to. If there is an existing version of the plugin registered, it * will overwrite that with the one from this server. */ public class NgcBDERegistrar extends NgcRegistrar { private static final Logger LOGGER = Logger.getLogger(NgcBDERegistrar.class); private String packageName = NgcConstants.PLUGIN_ZIP_NAME; public void initNgcRegistration() { String vcVersion = VcContext.getVcVersion(); LOGGER.info("Get VC version:"+vcVersion); if("5.1.0".equals(vcVersion)) { packageName = NgcConstants.PLUGIN_ZIP_NAME + "-5.1.0"; } LOGGER.info("Packaging NGC BDE plugin tarball..."); try{ packageNgcTarball(); } catch (IOException ex) { LOGGER.error("Packaging NGC BDE plugin tarball fails due to "+ ex.getMessage()); } LOGGER.info("Starting to register NGC BDE plugin..."); VcContext.inVcSessionDo(new VcSession<Void>() { @Override protected Void body() throws Exception { vcService = VcContext.getService(); extensionManager = vcService.getExtensionManager(); LOGGER.info("get extensionManager..."); Extension extension = extensionManager.findExtension(NgcConstants.NGC_KEY); LOGGER.info("get extension..." + NgcConstants.NGC_KEY); if (extension == null) { LOGGER.info("register extension..."); registerExtension(); } else { LOGGER.info("update extension..."); updateExtension(); } LOGGER.info("NGC BDE plugin auto-installation succeeded!"); return null; } }); } private static String LOCAL_HOST = "localhost"; private static int PORT_NUM = 443; @Override protected Extension generateNgcExtension() { try { String pluginUrl = NgcConstants.NGC_PLUGIN_URL_PREFIX + getVmIpAddress() + NgcConstants.NGC_PLUGIN_URL_SUFFIX + packageName + ".zip"; Extension extension = new ExtensionImpl(); extension.setKey(NgcConstants.NGC_KEY); extension.setVersion(NgcConstants.NGC_VERSION); extension.setCompany(NgcConstants.NGC_COMPANY); Description description = new DescriptionImpl(); description.setLabel(NgcConstants.NGC_LABEL); description.setSummary(NgcConstants.NGC_SUMMARY); extension.setDescription(description); ClientInfo clientInfo = new ClientInfoImpl(); clientInfo.setCompany(NgcConstants.NGC_COMPANY); clientInfo.setDescription(description); clientInfo.setType(NgcConstants.NGC_CLIENT_TYPE); clientInfo.setUrl(pluginUrl); clientInfo.setVersion(NgcConstants.NGC_VERSION); ClientInfo[] clientList = { clientInfo }; extension.setClient(clientList); ServerInfo serverInfo = new ServerInfoImpl(); String[] adminEmailList = { NgcConstants.NGC_ADMIN_EMAIL }; serverInfo.setAdminEmail(adminEmailList); serverInfo.setCompany(NgcConstants.NGC_COMPANY); serverInfo.setDescription(description); String thumbPrint = getCertThumbPrint(); serverInfo.setServerThumbprint(thumbPrint); serverInfo.setType(NgcConstants.NGC_SERVER_TYPE); serverInfo.setUrl(pluginUrl); ServerInfo serverInfoMgmt = null; String mgmtMoref = Configuration.getString(Constants.BDE_SERVER_VM_MOBID); if (mgmtMoref.length() > 0) { serverInfoMgmt = new ServerInfoImpl(); serverInfoMgmt.setAdminEmail(adminEmailList); serverInfoMgmt.setCompany(NgcConstants.NGC_COMPANY); serverInfoMgmt.setDescription(description); serverInfoMgmt.setType(mgmtMoref); serverInfoMgmt.setUrl(pluginUrl); } if (serverInfoMgmt == null) { ServerInfo[] serverList = { serverInfo }; extension.setServer(serverList); } else { ServerInfo[] serverList = { serverInfo, serverInfoMgmt }; extension.setServer(serverList); } GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance(); extension.setLastHeartbeatTime(calendar); return extension; } catch (Exception e) { throw new RuntimeException(e); } } private String getCertThumbPrint(){ try { KeyStore store = JksKeyStoreUtil.loadKeyStore(Configuration.getString("ngc.extension.keystore"), Configuration.getString("cms.keystore_pswd")); AuAssert.check(store != null); Certificate cert = store.getCertificate(Configuration.getString("ngc.extension.keystore_alias")); String thumbPrint = CmsKeyStore.parseThumbPrint(cert); LOGGER.info("Serengeti server thrumb print: "+thumbPrint); return thumbPrint; } catch (Exception e) { LOGGER.error("fail to retrieve server thrumb print"); } return null; } private void packageNgcTarball() throws ZipException, IOException { Properties properties = new Properties(); String mgmtRefId = Configuration.getString(Constants.BDE_SERVER_VM_MOBID); String mgmtExtensionKey = "com.vmware.aurora.vcext.instance-"; String serverGuid = VcContext.getServerGuid(); String[] mgmtRefIdFields = mgmtRefId.split("-"); if (mgmtRefIdFields.length > 1) { String vmId = mgmtRefIdFields[mgmtRefIdFields.length - 1]; vmId = Integer.toHexString(Integer.parseInt(vmId)); mgmtExtensionKey = mgmtExtensionKey + vmId; } properties.setProperty("mgmtExtensionKey", mgmtExtensionKey); properties.setProperty("mgmtRefId", mgmtRefId); properties.setProperty("serverGuid", serverGuid); NgcZipPacker packer = new NgcZipPacker(properties,packageName); packer.repack(); String sudoCmd = CommonUtil.getCustomizedSudoCmd(); String chmodCommand = sudoCmd + " chmod 644 /opt/serengeti/www/vcplugin/*"; ShellCommandExecutor.execCmd(chmodCommand, null, null, 0, "Changing files mode to 644 under directory vcplugin"); } }