mirror of https://github.com/apache/cloudstack.git
Add support to add and delete and update static routes on Netris (#37)
* Add support to add static routes in Netris * support to delete static routes on netris * add defensive check for nextHop * Add support to update static routes * add state * pass empty list for switched to avoid timeout * Netris: search static route by name and next hop if exists --------- Co-authored-by: Wei Zhou <weizhou@apache.org>
This commit is contained in:
parent
bbb7acccbe
commit
5ac35a2d8b
|
|
@ -22,14 +22,28 @@ import com.cloud.network.vpc.Vpc;
|
|||
|
||||
public interface NetrisService {
|
||||
boolean createIPAMAllocationsForZoneLevelPublicRanges(long zoneId);
|
||||
|
||||
boolean createVpcResource(long zoneId, long accountId, long domainId, Long vpcId, String vpcName, boolean sourceNatEnabled, String cidr, boolean isVpcNetwork);
|
||||
|
||||
boolean deleteVpcResource(long zoneId, long accountId, long domainId, Vpc vpc);
|
||||
|
||||
boolean createVnetResource(Long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr);
|
||||
|
||||
boolean deleteVnetResource(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr);
|
||||
|
||||
boolean createSnatRule(long zoneId, long accountId, long domainId, String vpcName, long vpcId, String networkName, long networkId, boolean isForVpc, String vpcCidr, String sourceNatIp);
|
||||
|
||||
boolean createPortForwardingRule(long zoneId, long accountId, long domainId, String vpcName, long vpcId, String networkName, Long networkId, boolean isForVpc, String vpcCidr, SDNProviderNetworkRule networkRule);
|
||||
|
||||
boolean deletePortForwardingRule(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, boolean isForVpc, String vpcCidr, SDNProviderNetworkRule networkRule);
|
||||
|
||||
boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address);
|
||||
|
||||
boolean createStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String vpcCidr, String staticNatIp, String vmIp);
|
||||
|
||||
boolean deleteStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String staticNatIp);
|
||||
|
||||
boolean addOrUpdateStaticRoute(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId, boolean updateRoute);
|
||||
|
||||
boolean deleteStaticRoute(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public interface StaticRoute extends ControlledEntity, Identity, InternalIdentit
|
|||
Staged, // route been created but has never got through network rule conflict detection. Routes in this state can not be sent to VPC virtual router.
|
||||
Add, // Add means the route has been created and has gone through network rule conflict detection.
|
||||
Active, // Route has been sent to the VPC router and reported to be active.
|
||||
Update,
|
||||
Revoke, // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database.
|
||||
Deleting // rule has been revoked and is scheduled for deletion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.agent.api;
|
||||
|
||||
public class AddOrUpdateNetrisStaticRouteCommand extends NetrisCommand {
|
||||
private String prefix;
|
||||
private String nextHop;
|
||||
private Long routeId;
|
||||
private boolean updateRoute;
|
||||
|
||||
public AddOrUpdateNetrisStaticRouteCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, String prefix, String nextHop, Long routeId, boolean updateRoute) {
|
||||
super(zoneId, accountId, domainId, name, id, isVpc);
|
||||
this.prefix = prefix;
|
||||
this.nextHop = nextHop;
|
||||
this.routeId = routeId;
|
||||
this.updateRoute = updateRoute;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getNextHop() {
|
||||
return nextHop;
|
||||
}
|
||||
|
||||
public Long getRouteId() {
|
||||
return routeId;
|
||||
}
|
||||
|
||||
public boolean isUpdateRoute() {
|
||||
return updateRoute;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.agent.api;
|
||||
|
||||
public class DeleteNetrisStaticRouteCommand extends AddOrUpdateNetrisStaticRouteCommand {
|
||||
public DeleteNetrisStaticRouteCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, String prefix, String nextHop, Long routeId) {
|
||||
super(zoneId, accountId, domainId, name, id, isVpc, prefix, nextHop, routeId, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -28,10 +28,12 @@ import com.cloud.agent.api.StartupCommand;
|
|||
import com.cloud.host.Host;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.NetrisAnswer;
|
||||
|
|
@ -102,7 +104,11 @@ public class NetrisResource implements ServerResource {
|
|||
} else if (cmd instanceof DeleteNetrisNatRuleCommand) {
|
||||
return executeRequest((DeleteNetrisNatRuleCommand) cmd);
|
||||
} else if (cmd instanceof CreateOrUpdateNetrisNatCommand) {
|
||||
return executeRequest((CreateOrUpdateNetrisNatCommand) cmd);
|
||||
return executeRequest((CreateOrUpdateNetrisNatCommand) cmd);
|
||||
} else if (cmd instanceof DeleteNetrisStaticRouteCommand) {
|
||||
return executeRequest((DeleteNetrisStaticRouteCommand) cmd);
|
||||
} else if (cmd instanceof AddOrUpdateNetrisStaticRouteCommand) {
|
||||
return executeRequest((AddOrUpdateNetrisStaticRouteCommand) cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
|
|
@ -297,6 +303,22 @@ public class NetrisResource implements ServerResource {
|
|||
return new NetrisAnswer(cmd, true, "OK");
|
||||
}
|
||||
|
||||
private Answer executeRequest(AddOrUpdateNetrisStaticRouteCommand cmd) {
|
||||
boolean result = netrisApiClient.addOrUpdateStaticRoute(cmd);
|
||||
if (!result) {
|
||||
return new NetrisAnswer(cmd, false, String.format("Failed to add static route for VPC: %s, prefix: %s, nextHop: %s ", cmd.getName(), cmd.getPrefix(), cmd.getNextHop()));
|
||||
}
|
||||
return new NetrisAnswer(cmd, true, "OK");
|
||||
}
|
||||
|
||||
private Answer executeRequest(DeleteNetrisStaticRouteCommand cmd) {
|
||||
boolean result = netrisApiClient.deleteStaticRoute(cmd);
|
||||
if (!result) {
|
||||
return new NetrisAnswer(cmd, false, String.format("Failed to add static route for VPC: %s, prefix: %s, nextHop: %s ", cmd.getName(), cmd.getPrefix(), cmd.getNextHop()));
|
||||
}
|
||||
return new NetrisAnswer(cmd, true, "OK");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import org.apache.commons.lang3.ArrayUtils;
|
|||
public class NetrisResourceObjectUtils {
|
||||
|
||||
public enum NetrisObjectType {
|
||||
VPC, IPAM_ALLOCATION, IPAM_SUBNET, VNET, SNAT, STATICNAT, DNAT
|
||||
VPC, IPAM_ALLOCATION, IPAM_SUBNET, VNET, SNAT, STATICNAT, DNAT, STATICROUTE
|
||||
}
|
||||
|
||||
public static String retrieveNetrisResourceObjectName(NetrisCommand cmd, NetrisObjectType netrisObjectType, String... suffixes) {
|
||||
|
|
@ -72,6 +72,10 @@ public class NetrisResourceObjectUtils {
|
|||
stringBuilder.append(String.format("%s%s-%s", prefix, suffixes[0], "DNAT"));
|
||||
suffixes = ArrayUtils.subarray(suffixes, 1, suffixes.length);
|
||||
break;
|
||||
case STATICROUTE:
|
||||
stringBuilder.append(String.format("%s%s-%s%s", prefix, suffixes[0], "ROUTE", suffixes[1]));
|
||||
suffixes = new String[0];
|
||||
break;
|
||||
case VNET:
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@ import io.netris.ApiException;
|
|||
import io.netris.model.GetSiteBody;
|
||||
import io.netris.model.VPCListing;
|
||||
import io.netris.model.response.TenantResponse;
|
||||
import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
|
||||
|
|
@ -74,4 +76,6 @@ public interface NetrisApiClient {
|
|||
boolean createOrUpdateDNATRule(CreateOrUpdateNetrisNatCommand cmd);
|
||||
boolean createStaticNatRule(CreateOrUpdateNetrisNatCommand cmd);
|
||||
boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd);
|
||||
boolean addOrUpdateStaticRoute(AddOrUpdateNetrisStaticRouteCommand cmd);
|
||||
boolean deleteStaticRoute(DeleteNetrisStaticRouteCommand cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import io.netris.ApiClient;
|
|||
import io.netris.ApiException;
|
||||
import io.netris.ApiResponse;
|
||||
import io.netris.api.v1.AuthenticationApi;
|
||||
import io.netris.api.v1.RoutesApi;
|
||||
import io.netris.api.v1.SitesApi;
|
||||
import io.netris.api.v1.TenantsApi;
|
||||
import io.netris.api.v2.IpamApi;
|
||||
|
|
@ -35,6 +36,7 @@ import io.netris.model.FilterByVpc;
|
|||
import io.netris.model.GetSiteBody;
|
||||
import io.netris.model.InlineResponse20015;
|
||||
import io.netris.model.InlineResponse20016;
|
||||
import io.netris.model.InlineResponse2003;
|
||||
import io.netris.model.InlineResponse2004;
|
||||
import io.netris.model.InlineResponse2004Data;
|
||||
import io.netris.model.IpTree;
|
||||
|
|
@ -48,6 +50,13 @@ import io.netris.model.NatGetBody;
|
|||
import io.netris.model.NatPostBody;
|
||||
import io.netris.model.NatPutBody;
|
||||
import io.netris.model.NatResponseGetOk;
|
||||
import io.netris.model.RoutesBody;
|
||||
import io.netris.model.RoutesBodyId;
|
||||
import io.netris.model.RoutesBodyVpcVpc;
|
||||
import io.netris.model.RoutesGetBody;
|
||||
import io.netris.model.RoutesPostBody;
|
||||
import io.netris.model.RoutesPutBody;
|
||||
import io.netris.model.RoutesResponseGetOk;
|
||||
import io.netris.model.SitesResponseOK;
|
||||
import io.netris.model.SubnetBody;
|
||||
import io.netris.model.SubnetResBody;
|
||||
|
|
@ -71,10 +80,12 @@ import io.netris.model.VnetsBody;
|
|||
import io.netris.model.response.AuthResponse;
|
||||
import io.netris.model.response.TenantResponse;
|
||||
import io.netris.model.response.TenantsResponse;
|
||||
import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
|
||||
|
|
@ -283,6 +294,176 @@ public class NetrisApiClientImpl implements NetrisApiClient {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addOrUpdateStaticRoute(AddOrUpdateNetrisStaticRouteCommand cmd) {
|
||||
String prefix = cmd.getPrefix();
|
||||
String nextHop = cmd.getNextHop();
|
||||
Long vpcId = cmd.getId();
|
||||
String vpcName = cmd.getName();
|
||||
boolean updateRoute = cmd.isUpdateRoute();
|
||||
try {
|
||||
String vpcSuffix = getNetrisVpcNameSuffix(vpcId, vpcName, null, null, true);
|
||||
String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, vpcSuffix);
|
||||
VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
|
||||
if (vpcResource == null) {
|
||||
logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] suffixes = new String[2];
|
||||
suffixes[0] = vpcId.toString();
|
||||
suffixes[1] = cmd.getRouteId().toString();
|
||||
String staticRouteId = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffixes);
|
||||
|
||||
Pair<Boolean, RoutesGetBody> existingStaticRoute = staticRouteExists(vpcResource.getId(), prefix, null, staticRouteId);
|
||||
if (updateRoute) {
|
||||
if (!existingStaticRoute.first()) {
|
||||
logger.error("The Netris static route {} does not exist for VPC {}", prefix, netrisVpcName);
|
||||
return false;
|
||||
}
|
||||
return updateStaticRouteInternal(existingStaticRoute.second().getId(), netrisVpcName, prefix, nextHop, staticRouteId);
|
||||
} else {
|
||||
if (existingStaticRoute.first()) {
|
||||
String existingNextHop = existingStaticRoute.second().getNextHop();
|
||||
if (existingNextHop != null && existingNextHop.equals(nextHop)) {
|
||||
logger.debug("The Netris static route {} already exists for VPC {}", prefix, netrisVpcName);
|
||||
return true;
|
||||
} else {
|
||||
logger.debug("The Netris static route {} already exists but has different next hop {} for VPC {}", prefix, nextHop, netrisVpcName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return addStaticRouteInternal(vpcResource, netrisVpcName, prefix, nextHop, staticRouteId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Error adding Netris static route", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean addStaticRouteInternal(VPCListing vpcResource, String netrisVpcName, String prefix, String nextHop, String staticRouteId) {
|
||||
try {
|
||||
RoutesApi routesApi = apiClient.getApiStubForMethod(RoutesApi.class);
|
||||
RoutesPostBody routesPostBody = new RoutesPostBody();
|
||||
routesPostBody.setPrefix(prefix);
|
||||
routesPostBody.setNextHop(nextHop);
|
||||
routesPostBody.setSiteId(new BigDecimal(siteId));
|
||||
routesPostBody.setStateStatus(RoutesBody.StateStatusEnum.ACTIVE);
|
||||
|
||||
RoutesBodyVpcVpc vpcBody = new RoutesBodyVpcVpc();
|
||||
vpcBody.setId(vpcResource.getId());
|
||||
vpcBody.setName(vpcResource.getName());
|
||||
vpcBody.setIsDefault(vpcResource.isIsDefault());
|
||||
vpcBody.setIsSystem(vpcResource.isIsSystem());
|
||||
routesPostBody.setVpc(vpcBody);
|
||||
|
||||
routesPostBody.setDescription(staticRouteId);
|
||||
routesPostBody.setStateStatus(RoutesBody.StateStatusEnum.ACTIVE);
|
||||
routesPostBody.setSwitches(Collections.emptyList());
|
||||
|
||||
InlineResponse2004 routeResponse = routesApi.apiRoutesPost(routesPostBody);
|
||||
if (routeResponse == null || !routeResponse.isIsSuccess()) {
|
||||
String reason = routeResponse == null ? "Empty response" : "Operation failed on Netris";
|
||||
logger.debug("The Netris static route creation failed for netris VPC - {}: {}", netrisVpcName, reason);
|
||||
throw new CloudRuntimeException(reason);
|
||||
}
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException("Error adding Netris static route", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean updateStaticRouteInternal(Integer id, String netrisVpcName, String prefix, String nextHop, String staticRouteId) {
|
||||
try {
|
||||
RoutesApi routesApi = apiClient.getApiStubForMethod(RoutesApi.class);
|
||||
RoutesPutBody routesPutBody = new RoutesPutBody();
|
||||
routesPutBody.setId(id);
|
||||
routesPutBody.setPrefix(prefix);
|
||||
routesPutBody.setNextHop(nextHop);
|
||||
routesPutBody.setSiteId(new BigDecimal(siteId));
|
||||
|
||||
routesPutBody.setDescription(staticRouteId);
|
||||
routesPutBody.setSwitches(Collections.emptyList());
|
||||
|
||||
InlineResponse2003 routeResponse = routesApi.apiRoutesPut(routesPutBody);
|
||||
if (routeResponse == null || !routeResponse.isIsSuccess()) {
|
||||
String reason = routeResponse == null ? "Empty response" : "Operation failed on Netris";
|
||||
logger.debug("Failed to update Netris static route for netris VPC - {}: {}", netrisVpcName, reason);
|
||||
throw new CloudRuntimeException(reason);
|
||||
}
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException("Error updating Netris static route", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteStaticRoute(DeleteNetrisStaticRouteCommand cmd) {
|
||||
Long vpcId = cmd.getId();
|
||||
String vpcName = cmd.getName();
|
||||
String prefix = cmd.getPrefix();
|
||||
String nextHop = cmd.getNextHop();
|
||||
try {
|
||||
String vpcSuffix = getNetrisVpcNameSuffix(vpcId, vpcName, null, null, true);
|
||||
String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, vpcSuffix);
|
||||
VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
|
||||
if (vpcResource == null) {
|
||||
logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] suffixes = new String[2];
|
||||
suffixes[0] = vpcId.toString();
|
||||
suffixes[1] = cmd.getRouteId().toString();
|
||||
String staticRouteId = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffixes);
|
||||
Pair<Boolean, RoutesGetBody> existingStaticRoute = staticRouteExists(vpcResource.getId(), prefix, nextHop, staticRouteId);
|
||||
|
||||
if (Boolean.FALSE.equals(existingStaticRoute.first())) {
|
||||
logger.debug("The Netris static route {} does not exist for VPC {}", prefix, netrisVpcName);
|
||||
return true;
|
||||
}
|
||||
RoutesGetBody existingRoute = existingStaticRoute.second();
|
||||
RoutesApi routesApi = apiClient.getApiStubForMethod(RoutesApi.class);
|
||||
RoutesBodyId id = new RoutesBodyId();
|
||||
id.setId(existingRoute.getId());
|
||||
InlineResponse2003 routeDeleteResponse = routesApi.apiRoutesDelete(id);
|
||||
if (routeDeleteResponse == null || !routeDeleteResponse.isIsSuccess()) {
|
||||
String reason = routeDeleteResponse == null ? "Empty response" : "Operation failed on Netris";
|
||||
logger.debug("The Netris static route deletion failed for netris VPC - {}: {}", netrisVpcName, reason);
|
||||
throw new CloudRuntimeException(reason);
|
||||
}
|
||||
return true;
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException("Error deleting Netris static route", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Pair<Boolean, RoutesGetBody> staticRouteExists(Integer netrisVpcId, String prefix, String nextHop, String description) {
|
||||
try {
|
||||
FilterByVpc vpcFilter = new FilterByVpc();
|
||||
vpcFilter.add(netrisVpcId);
|
||||
FilterBySites sitesFilter = new FilterBySites();
|
||||
sitesFilter.add(siteId);
|
||||
RoutesApi routesApi = apiClient.getApiStubForMethod(RoutesApi.class);
|
||||
RoutesResponseGetOk routesResponseGetOk = routesApi.apiRoutesGet(sitesFilter, vpcFilter);
|
||||
if (Objects.isNull(routesResponseGetOk) || Boolean.FALSE.equals(routesResponseGetOk.isIsSuccess())) {
|
||||
logger.warn("Failed to retrieve static routes");
|
||||
return new Pair<>(false, null);
|
||||
}
|
||||
List<RoutesGetBody> routesList = routesResponseGetOk.getData();
|
||||
List<RoutesGetBody> filteredList = routesList.stream()
|
||||
.filter(x -> x.getName().equals(prefix) &&
|
||||
(Objects.isNull(nextHop) || x.getNextHop().equals(nextHop)))
|
||||
.collect(Collectors.toList());
|
||||
return new Pair<>(!filteredList.isEmpty(), filteredList.isEmpty() ? null : filteredList.get(0));
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException("Error checking Netris static routes", e);
|
||||
}
|
||||
return new Pair<>(false, null);
|
||||
}
|
||||
|
||||
private void deleteNatSubnet(Integer netrisVpcId, String natIp) {
|
||||
FilterByVpc vpcFilter = new FilterByVpc();
|
||||
vpcFilter.add(netrisVpcId);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ import com.cloud.network.rules.PortForwardingRule;
|
|||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.network.vpc.NetworkACLItem;
|
||||
import com.cloud.network.vpc.PrivateGateway;
|
||||
import com.cloud.network.vpc.StaticRoute;
|
||||
import com.cloud.network.vpc.StaticRouteProfile;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
|
|
@ -410,6 +411,15 @@ public class NetrisElement extends AdapterBase implements DhcpServiceProvider, D
|
|||
|
||||
@Override
|
||||
public boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes) throws ResourceUnavailableException {
|
||||
for(StaticRouteProfile staticRoute : routes) {
|
||||
if (StaticRoute.State.Add == staticRoute.getState()) {
|
||||
netrisService.addOrUpdateStaticRoute(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getName(), vpc.getId(), true, staticRoute.getCidr(), staticRoute.getGateway(), staticRoute.getId(), false);
|
||||
} else if (StaticRoute.State.Revoke == staticRoute.getState()) {
|
||||
netrisService.deleteStaticRoute(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getName(), vpc.getId(), true, staticRoute.getCidr(), staticRoute.getGateway(), staticRoute.getId());
|
||||
} else if (StaticRoute.State.Update == staticRoute.getState()) {
|
||||
netrisService.addOrUpdateStaticRoute(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getName(), vpc.getId(), true, staticRoute.getCidr(), staticRoute.getGateway(), staticRoute.getId(), true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,12 @@ import com.cloud.utils.net.NetUtils;
|
|||
import inet.ipaddr.IPAddress;
|
||||
import inet.ipaddr.IPAddressString;
|
||||
import io.netris.model.NatPostBody;
|
||||
import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.NetrisAnswer;
|
||||
|
|
@ -338,6 +340,20 @@ public class NetrisServiceImpl implements NetrisService, Configurable {
|
|||
return answer.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addOrUpdateStaticRoute(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId, boolean updateRoute) {
|
||||
AddOrUpdateNetrisStaticRouteCommand cmd = new AddOrUpdateNetrisStaticRouteCommand(zoneId, accountId, domainId, networkResourceName, networkResourceId, isForVpc, prefix, nextHop, routeId, updateRoute);
|
||||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteStaticRoute(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId) {
|
||||
DeleteNetrisStaticRouteCommand cmd = new DeleteNetrisStaticRouteCommand(zoneId, accountId, domainId, networkResourceName, networkResourceId, isForVpc, prefix, nextHop, routeId);
|
||||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
private String getResourceSuffix(Long vpcId, Long networkId, boolean isForVpc) {
|
||||
String suffix;
|
||||
if (isForVpc) {
|
||||
|
|
|
|||
|
|
@ -76,4 +76,14 @@ public class NetrisServiceMockTest implements NetrisService {
|
|||
public boolean deleteStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String staticNatIp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addOrUpdateStaticRoute(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId, boolean updateRoute) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteStaticRoute(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue