mirror of https://github.com/apache/cloudstack.git
parent
197332464f
commit
10544e287b
1
plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml
Normal file → Executable file
1
plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml
Normal file → Executable file
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
<bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl" />
|
||||
<bean id="BaremetalVlanManager" class="com.cloud.baremetal.manager.BaremetalVlanManagerImpl" />
|
||||
<bean id="Force10BaremetalSwitchBackend" class="com.cloud.baremetal.networkservice.Force10BaremetalSwitchBackend" />
|
||||
|
||||
<bean id="BaremetalKickStartPxeService"
|
||||
class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl" />
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public class BaremetalRct {
|
|||
public static class HostEntry {
|
||||
private String uuid;
|
||||
private String mac;
|
||||
private int port;
|
||||
private String port;
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
|
|
@ -83,11 +83,11 @@ public class BaremetalRct {
|
|||
this.mac = mac;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
public void setPort(String port) {
|
||||
this.port = port;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,11 @@
|
|||
package com.cloud.baremetal.manager;
|
||||
|
||||
import com.cloud.baremetal.networkservice.BaremetalRctResponse;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import org.apache.cloudstack.api.AddBaremetalRctCmd;
|
||||
|
||||
/**
|
||||
|
|
@ -29,4 +32,8 @@ public interface BaremetalVlanManager extends Manager, PluggableService {
|
|||
public static final String BAREMETAL_SYSTEM_ACCOUNT_NAME = "baremetal-system-account";
|
||||
|
||||
BaremetalRctResponse addRct(AddBaremetalRctCmd cmd);
|
||||
|
||||
void prepareVlan(Network nw, DeployDestination destHost);
|
||||
|
||||
void releaseVlan(Network nw, VirtualMachineProfile vm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@ package com.cloud.baremetal.manager;
|
|||
import com.cloud.baremetal.database.BaremetalRctDao;
|
||||
import com.cloud.baremetal.database.BaremetalRctVO;
|
||||
import com.cloud.baremetal.networkservice.BaremetalRctResponse;
|
||||
import com.cloud.baremetal.networkservice.BaremetalSwitchBackend;
|
||||
import com.cloud.baremetal.networkservice.BaremetalVlanStruct;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
|
|
@ -29,6 +36,8 @@ import com.cloud.user.dao.UserDao;
|
|||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.cloudstack.api.AddBaremetalRctCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
|
||||
|
|
@ -38,7 +47,9 @@ import javax.inject.Inject;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
|
@ -50,12 +61,21 @@ public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVl
|
|||
@Inject
|
||||
private BaremetalRctDao rctDao;
|
||||
@Inject
|
||||
private HostDao hostDao;
|
||||
@Inject
|
||||
private AccountDao acntDao;
|
||||
@Inject
|
||||
private UserDao userDao;
|
||||
@Inject
|
||||
private AccountManager acntMgr;
|
||||
|
||||
private Map<String, BaremetalSwitchBackend> backends = new HashMap<>();
|
||||
|
||||
private class RackPair {
|
||||
BaremetalRct.Rack rack;
|
||||
BaremetalRct.HostEntry host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaremetalRctResponse addRct(AddBaremetalRctCmd cmd) {
|
||||
try {
|
||||
|
|
@ -87,11 +107,95 @@ public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVl
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareVlan(Network nw, DeployDestination destHost) {
|
||||
List<BaremetalRctVO> vos = rctDao.listAll();
|
||||
if (vos.isEmpty()) {
|
||||
throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one");
|
||||
}
|
||||
|
||||
BaremetalRctVO vo = vos.get(0);
|
||||
BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class);
|
||||
|
||||
RackPair rp = findRack(rct, destHost.getHost().getPrivateMacAddress());
|
||||
if (rp == null) {
|
||||
throw new CloudRuntimeException(String.format("cannot find any rack contains host[mac:%s], please double check your rack configuration file, update it and call addBaremetalRct again", destHost.getHost().getPrivateMacAddress()));
|
||||
}
|
||||
|
||||
int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri()));
|
||||
BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType());
|
||||
BaremetalVlanStruct struct = new BaremetalVlanStruct();
|
||||
struct.setHostMac(rp.host.getMac());
|
||||
struct.setPort(rp.host.getPort());
|
||||
struct.setSwitchIp(rp.rack.getL2Switch().getIp());
|
||||
struct.setSwitchPassword(rp.rack.getL2Switch().getPassword());
|
||||
struct.setSwitchType(rp.rack.getL2Switch().getType());
|
||||
struct.setSwitchUsername(rp.rack.getL2Switch().getUsername());
|
||||
struct.setVlan(vlan);
|
||||
backend.prepareVlan(struct);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseVlan(Network nw, VirtualMachineProfile vm) {
|
||||
List<BaremetalRctVO> vos = rctDao.listAll();
|
||||
if (vos.isEmpty()) {
|
||||
throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one");
|
||||
}
|
||||
|
||||
BaremetalRctVO vo = vos.get(0);
|
||||
BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class);
|
||||
HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId());
|
||||
RackPair rp = findRack(rct, host.getPrivateMacAddress());
|
||||
assert rp != null : String.format("where is my rack???");
|
||||
|
||||
int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri()));
|
||||
BaremetalVlanStruct struct = new BaremetalVlanStruct();
|
||||
struct.setHostMac(rp.host.getMac());
|
||||
struct.setPort(rp.host.getPort());
|
||||
struct.setSwitchIp(rp.rack.getL2Switch().getIp());
|
||||
struct.setSwitchPassword(rp.rack.getL2Switch().getPassword());
|
||||
struct.setSwitchType(rp.rack.getL2Switch().getType());
|
||||
struct.setSwitchUsername(rp.rack.getL2Switch().getUsername());
|
||||
struct.setVlan(vlan);
|
||||
BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType());
|
||||
backend.removePortFromVlan(struct);
|
||||
}
|
||||
|
||||
private BaremetalSwitchBackend getSwitchBackend(String type) {
|
||||
BaremetalSwitchBackend backend = backends.get(type);
|
||||
if (backend == null) {
|
||||
throw new CloudRuntimeException(String.format("cannot find switch backend[type:%s]", type));
|
||||
}
|
||||
return backend;
|
||||
}
|
||||
|
||||
private RackPair findRack(BaremetalRct rct, String mac) {
|
||||
for (BaremetalRct.Rack rack : rct.getRacks()) {
|
||||
for (BaremetalRct.HostEntry host : rack.getHosts()) {
|
||||
if (mac.equals(host.getMac())) {
|
||||
RackPair p = new RackPair();
|
||||
p.host = host;
|
||||
p.rack = rack;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Baremetal Vlan Manager";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
List<Class<?>> cmds = new ArrayList<Class<?>>();
|
||||
cmds.add(AddBaremetalRctCmd.class);
|
||||
return cmds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
QueryBuilder<AccountVO> acntq = QueryBuilder.create(AccountVO.class);
|
||||
|
|
@ -126,12 +230,4 @@ public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVl
|
|||
userDao.update(user.getId(), user);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
List<Class<?>> cmds = new ArrayList<Class<?>>();
|
||||
cmds.add(AddBaremetalRctCmd.class);
|
||||
return cmds;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,11 @@
|
|||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
import com.cloud.baremetal.database.BaremetalPxeVO;
|
||||
import com.cloud.baremetal.manager.BaremetalVlanManager;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
|
|
@ -67,6 +70,10 @@ public class BaremetalPxeElement extends AdapterBase implements NetworkElement {
|
|||
VMInstanceDao _vmDao;
|
||||
@Inject
|
||||
NicDao _nicDao;
|
||||
@Inject
|
||||
BaremetalVlanManager vlanMgr;
|
||||
@Inject
|
||||
DataCenterDao zoneDao;
|
||||
|
||||
static {
|
||||
Capability cap = new Capability(BaremetalPxeManager.BAREMETAL_PXE_CAPABILITY);
|
||||
|
|
@ -133,15 +140,31 @@ public class BaremetalPxeElement extends AdapterBase implements NetworkElement {
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if (dest.getDataCenter().getNetworkType() == DataCenter.NetworkType.Advanced){
|
||||
prepareVlan(network, dest);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void prepareVlan(Network network, DeployDestination dest) {
|
||||
vlanMgr.prepareVlan(network, dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException,
|
||||
ResourceUnavailableException {
|
||||
DataCenterVO dc = zoneDao.findById(vm.getVirtualMachine().getDataCenterId());
|
||||
if (dc.getNetworkType() == DataCenter.NetworkType.Advanced) {
|
||||
releaseVlan(network, vm);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void releaseVlan(Network network, VirtualMachineProfile vm) {
|
||||
vlanMgr.releaseVlan(network, vm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public interface BaremetalSwitchBackend {
|
||||
String getSwitchBackendType();
|
||||
|
||||
void prepareVlan(BaremetalVlanStruct struct);
|
||||
|
||||
void removePortFromVlan(BaremetalVlanStruct struct);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public class BaremetalVlanStruct {
|
||||
private String switchType;
|
||||
private String switchIp;
|
||||
private String switchUsername;
|
||||
private String switchPassword;
|
||||
private String hostMac;
|
||||
private String port;
|
||||
private int vlan;
|
||||
|
||||
public String getSwitchType() {
|
||||
return switchType;
|
||||
}
|
||||
|
||||
public void setSwitchType(String switchType) {
|
||||
this.switchType = switchType;
|
||||
}
|
||||
|
||||
public String getSwitchIp() {
|
||||
return switchIp;
|
||||
}
|
||||
|
||||
public void setSwitchIp(String switchIp) {
|
||||
this.switchIp = switchIp;
|
||||
}
|
||||
|
||||
public String getSwitchUsername() {
|
||||
return switchUsername;
|
||||
}
|
||||
|
||||
public void setSwitchUsername(String switchUsername) {
|
||||
this.switchUsername = switchUsername;
|
||||
}
|
||||
|
||||
public String getSwitchPassword() {
|
||||
return switchPassword;
|
||||
}
|
||||
|
||||
public void setSwitchPassword(String switchPassword) {
|
||||
this.switchPassword = switchPassword;
|
||||
}
|
||||
|
||||
public String getHostMac() {
|
||||
return hostMac;
|
||||
}
|
||||
|
||||
public void setHostMac(String hostMac) {
|
||||
this.hostMac = hostMac;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public int getVlan() {
|
||||
return vlan;
|
||||
}
|
||||
|
||||
public void setVlan(int vlan) {
|
||||
this.vlan = vlan;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.xmlobject.XmlObject;
|
||||
import com.cloud.utils.xmlobject.XmlObjectParser;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
||||
private Logger logger = Logger.getLogger(Force10BaremetalSwitchBackend.class);
|
||||
public static final String TYPE = "Force10";
|
||||
|
||||
RestTemplate rest = new RestTemplate();
|
||||
|
||||
private String buildLink(String switchIp, Integer vlan) {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
||||
builder.scheme("http");
|
||||
builder.host(switchIp);
|
||||
builder.port(8008);
|
||||
builder.path("/api/running/ftos/interface/vlan");
|
||||
if (vlan != null) {
|
||||
builder.path(vlan.toString());
|
||||
}
|
||||
return builder.build().toUriString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwitchBackendType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareVlan(BaremetalVlanStruct struct) {
|
||||
String link = buildLink(struct.getSwitchIp(), struct.getVlan());
|
||||
HttpHeaders headers = createBasicAuthenticationHeader(struct);
|
||||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
|
||||
|
||||
if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
PortInfo port = new PortInfo(struct);
|
||||
XmlObject xml = new XmlObject("vlan").putElement("vlan-id", String.valueOf(struct.getVlan())).putElement("tagged",
|
||||
new XmlObject(port.interfaceType).putElement("name", port.port)
|
||||
).putElement("shutdown", "false");
|
||||
request = new HttpEntity<>(xml.toString(), headers);
|
||||
link = buildLink(struct.getSwitchIp(), null);
|
||||
rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
|
||||
if (rsp.getStatusCode() != HttpStatus.OK) {
|
||||
throw new CloudRuntimeException(String.format("unable to create vlan[%s] on force10 switch[ip:%s]. HTTP status code:%s, body dump:%s",
|
||||
struct.getVlan(), rsp.getStatusCode(), struct.getSwitchIp(), rsp.getBody()));
|
||||
}
|
||||
} else if (rsp.getStatusCode() == HttpStatus.OK) {
|
||||
PortInfo port = new PortInfo(struct);
|
||||
XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody());
|
||||
List<XmlObject> ports = xml.getAsList("tagged.tengigabitethernet");
|
||||
ports.addAll(xml.<XmlObject>getAsList("tagged.gigabitethernet"));
|
||||
ports.addAll(xml.<XmlObject>getAsList("tagged.fortyGigE"));
|
||||
for (XmlObject pxml : ports) {
|
||||
XmlObject name = pxml.get("name");
|
||||
if (port.port.equals(name.getText())) {
|
||||
logger.debug(String.format("port[%s] has joined in vlan[%s], no need to program again", struct.getPort(), struct.getVlan()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
XmlObject tag = xml.get("tagged");
|
||||
tag.putElement(port.interfaceType, new XmlObject("name").setText(port.port));
|
||||
request = new HttpEntity<>(xml.toString(), headers);
|
||||
link = buildLink(struct.getSwitchIp(), struct.getVlan());
|
||||
rsp = rest.exchange(link, HttpMethod.PUT, request, String.class);
|
||||
if (rsp.getStatusCode() != HttpStatus.NO_CONTENT) {
|
||||
throw new CloudRuntimeException(String.format("failed to program vlan[%s] for port[%s] on force10[ip:%s]. http status:%s, body dump:%s",
|
||||
struct.getVlan(), struct.getPort(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("force10[ip:%s] returns unexpected error[%s] when http getting %s, body dump:%s",
|
||||
struct.getSwitchIp(), rsp.getStatusCode(), link, rsp.getBody()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePortFromVlan(BaremetalVlanStruct struct) {
|
||||
String link = buildLink(struct.getSwitchIp(), struct.getVlan());
|
||||
HttpHeaders headers = createBasicAuthenticationHeader(struct);
|
||||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
|
||||
if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
logger.debug(String.format("vlan[%s] has been deleted on force10[ip:%s], no need to remove the port[%s] anymore", struct.getVlan(), struct.getSwitchIp(), struct.getPort()));
|
||||
} else if (rsp.getStatusCode() == HttpStatus.OK) {
|
||||
PortInfo port = new PortInfo(struct);
|
||||
XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody());
|
||||
List<XmlObject> ports = xml.getAsList("tagged.tengigabitethernet");
|
||||
ports.addAll(xml.<XmlObject>getAsList("tagged.gigabitethernet"));
|
||||
ports.addAll(xml.<XmlObject>getAsList("tagged.fortyGigE"));
|
||||
List<XmlObject> newPorts = new ArrayList<>();
|
||||
boolean needRemove = false;
|
||||
for (XmlObject pxml : ports) {
|
||||
XmlObject name = pxml.get("name");
|
||||
if (port.port.equals(name.getText())) {
|
||||
needRemove = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
newPorts.add(pxml);
|
||||
}
|
||||
|
||||
if (!needRemove) {
|
||||
return;
|
||||
}
|
||||
|
||||
xml.putElement("tagged", newPorts);
|
||||
|
||||
request = new HttpEntity<>(xml.toString(), headers);
|
||||
rsp = rest.exchange(link, HttpMethod.PUT, request, String.class);
|
||||
if (rsp.getStatusCode() != HttpStatus.NO_CONTENT) {
|
||||
throw new CloudRuntimeException(String.format("failed to program vlan[%s] for port[%s] on force10[ip:%s]. http status:%s, body dump:%s",
|
||||
struct.getVlan(), struct.getPort(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
|
||||
} else {
|
||||
logger.debug(String.format("removed port[%s] from vlan[%s] on force10[ip:%s]", struct.getPort(), struct.getVlan(), struct.getSwitchIp()));
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("force10[ip:%s] returns unexpected error[%s] when http getting %s, body dump:%s",
|
||||
struct.getSwitchIp(), rsp.getStatusCode(), link, rsp.getBody()));
|
||||
}
|
||||
}
|
||||
|
||||
private HttpHeaders createBasicAuthenticationHeader(BaremetalVlanStruct struct) {
|
||||
String plainCreds = String.format("%s:%s", struct.getSwitchUsername(), struct.getSwitchPassword());
|
||||
byte[] plainCredsBytes = plainCreds.getBytes();
|
||||
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
|
||||
String base64Creds = new String(base64CredsBytes);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Authorization", "Basic " + base64Creds);
|
||||
return headers;
|
||||
}
|
||||
|
||||
private class PortInfo {
|
||||
static final String G_IFACE = "gigabitethernet";
|
||||
static final String TEN_G_IFACE = "tengigabitethernet";
|
||||
static final String FOURTY_G_IFACE = "fortyGigE";
|
||||
|
||||
private String interfaceType;
|
||||
private String port;
|
||||
|
||||
PortInfo(BaremetalVlanStruct struct) {
|
||||
String[] ps = StringUtils.split(struct.getPort(), ":");
|
||||
if (ps.length == 1) {
|
||||
interfaceType = TEN_G_IFACE;
|
||||
port = ps[0];
|
||||
} else if (ps.length == 2) {
|
||||
interfaceType = ps[0];
|
||||
if (!interfaceType.equals(G_IFACE) && !interfaceType.equals(TEN_G_IFACE) && !interfaceType.equals(FOURTY_G_IFACE)) {
|
||||
throw new CloudRuntimeException(String.format("wrong port definition[%s]. The prefix must be one of [%s,%s,%s]", struct.getPort(), G_IFACE, TEN_G_IFACE, FOURTY_G_IFACE));
|
||||
}
|
||||
port = ps[1];
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("wrong port definition[%s]. Force10 port should be in format of interface_type:port_identity, for example: tengigabitethernet:1/3", struct.getPort()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1841,6 +1841,14 @@ public enum Config {
|
|||
"The maximum number of retrying times to search for an available IPv6 address in the table",
|
||||
null),
|
||||
|
||||
BaremetalEnableCompleteNotification(
|
||||
"Advanced",
|
||||
ManagementServer.class,
|
||||
Boolean.class,
|
||||
"baremetal.provision.done.notification",
|
||||
"false",
|
||||
"Enable provision done notification through virtual router",
|
||||
null),
|
||||
BaremetalPeerHypervisorType(
|
||||
"Advanced",
|
||||
ManagementServer.class,
|
||||
|
|
|
|||
|
|
@ -16,46 +16,6 @@
|
|||
// under the License.
|
||||
package com.cloud.network;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
|
|
@ -163,6 +123,7 @@ import com.cloud.utils.db.DB;
|
|||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
|
|
@ -189,6 +150,44 @@ import com.cloud.vm.dao.NicSecondaryIpDao;
|
|||
import com.cloud.vm.dao.NicSecondaryIpVO;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* NetworkServiceImpl implements NetworkService.
|
||||
|
|
@ -3854,11 +3853,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
|||
addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalUserdataProvider", null, null);
|
||||
} else if (dvo.getNetworkType() == NetworkType.Advanced) {
|
||||
addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalPxeProvider", null, null);
|
||||
enableBaremetalProvider("BaremetalPxeProvider");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void enableBaremetalProvider(String providerName) {
|
||||
QueryBuilder<PhysicalNetworkServiceProviderVO> q = QueryBuilder.create(PhysicalNetworkServiceProviderVO.class);
|
||||
q.and(q.entity().getProviderName(), SearchCriteria.Op.EQ, providerName);
|
||||
PhysicalNetworkServiceProviderVO provider = q.find();
|
||||
provider.setState(PhysicalNetworkServiceProvider.State.Enabled);
|
||||
_pNSPDao.update(provider.getId(), provider);
|
||||
}
|
||||
|
||||
protected boolean isNetworkSystem(Network network) {
|
||||
NetworkOffering no = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
|
||||
if (no.isSystemOnly()) {
|
||||
|
|
|
|||
|
|
@ -17,52 +17,6 @@
|
|||
|
||||
package com.cloud.network.router;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
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.alert.AlertService;
|
||||
import org.apache.cloudstack.alert.AlertService.AlertType;
|
||||
import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
|
||||
import org.apache.cloudstack.config.ApiServiceConfiguration;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.framework.config.ConfigDepot;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
|
||||
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.Listener;
|
||||
import com.cloud.agent.api.AgentControlAnswer;
|
||||
|
|
@ -255,6 +209,7 @@ import com.cloud.utils.db.EntityManager;
|
|||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GlobalLock;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
|
|
@ -288,6 +243,49 @@ import com.cloud.vm.dao.NicIpAliasVO;
|
|||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.apache.cloudstack.alert.AlertService;
|
||||
import org.apache.cloudstack.alert.AlertService.AlertType;
|
||||
import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
|
||||
import org.apache.cloudstack.config.ApiServiceConfiguration;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.framework.config.ConfigDepot;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
|
||||
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* VirtualNetworkApplianceManagerImpl manages the different types of virtual network appliances available in the Cloud Stack.
|
||||
|
|
@ -2320,6 +2318,18 @@ VirtualMachineGuru, Listener, Configurable, StateListener<State, VirtualMachine.
|
|||
}
|
||||
}
|
||||
|
||||
if (Boolean.valueOf(_configDao.getValue("baremetal.provision.done.notification"))) {
|
||||
QueryBuilder<UserVO> acntq = QueryBuilder.create(UserVO.class);
|
||||
acntq.and(acntq.entity().getUsername(), SearchCriteria.Op.EQ, "baremetal-system-account");
|
||||
UserVO user = acntq.find();
|
||||
if (user == null) {
|
||||
s_logger.warn(String.format("global setting[baremetal.provision.done.notification] is enabled but user baremetal-system-account is not found. Baremetal provision done notification will not be enabled"));
|
||||
} else {
|
||||
buf.append(String.format(" baremetalnotificationsecuritykey=%s", user.getSecretKey()));
|
||||
buf.append(String.format(" baremetalnotificationapikey=%s", user.getApiKey()));
|
||||
}
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ public class XmlObject {
|
|||
return this;
|
||||
}
|
||||
|
||||
public void removeElement(String key) {
|
||||
elements.remove(key);
|
||||
}
|
||||
|
||||
private Object recurGet(XmlObject obj, Iterator<String> it) {
|
||||
String key = it.next();
|
||||
Object e = obj.elements.get(key);
|
||||
|
|
|
|||
Loading…
Reference in New Issue