Skip to content

Commit

Permalink
Fix DeleteOptions on Public Ip Address (issue#38806) (#39096)
Browse files Browse the repository at this point in the history
Fix DeleteOptions on Public Ip Address (issue#38806)
  • Loading branch information
v-hongli1 authored Mar 27, 2024
1 parent 00db29e commit 38cf774
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Features Added

- Supported setting `DeleteOptions` for public IP addresses associated with `NetworkInterface`.

### Breaking Changes

### Bugs Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "java",
"TagPrefix": "java/resourcemanager/azure-resourcemanager-network",
"Tag": "java/resourcemanager/azure-resourcemanager-network_271269e41a"
"Tag": "java/resourcemanager/azure-resourcemanager-network_03b4909e5e"
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.azure.resourcemanager.network.NetworkManager;
import com.azure.resourcemanager.network.fluent.models.ApplicationSecurityGroupInner;
import com.azure.resourcemanager.network.models.ApplicationSecurityGroup;
import com.azure.resourcemanager.network.models.DeleteOptions;
import com.azure.resourcemanager.network.models.IpAllocationMethod;
import com.azure.resourcemanager.network.models.LoadBalancer;
import com.azure.resourcemanager.network.models.Network;
Expand All @@ -32,6 +33,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -60,11 +62,14 @@ class NetworkInterfaceImpl
private NetworkSecurityGroup existingNetworkSecurityGroupToAssociate;
/** cached related resources. */
private NetworkSecurityGroup networkSecurityGroup;
/** the name of specified ip config name */
private Map<String, DeleteOptions> specifiedIpConfigNames;

NetworkInterfaceImpl(String name, NetworkInterfaceInner innerModel, final NetworkManager networkManager) {
super(name, innerModel, networkManager);
this.nicName = name;
this.namer = this.manager().resourceManager().internalContext().createIdentifierProvider(this.nicName);
this.specifiedIpConfigNames = new HashMap<String, DeleteOptions>();
initializeChildrenFromInner();
}

Expand Down Expand Up @@ -563,9 +568,25 @@ protected void beforeCreating() {
.withNetworkSecurityGroup(new NetworkSecurityGroupInner().withId(networkSecurityGroup.id()));
}

NicIpConfigurationImpl.ensureConfigurations(this.nicIPConfigurations.values());
NicIpConfigurationImpl.ensureConfigurations(this.nicIPConfigurations.values(), this.specifiedIpConfigNames);

// Reset and update IP configs
this.innerModel().withIpConfigurations(innersFromWrappers(this.nicIPConfigurations.values()));
}

@Override
public NetworkInterfaceImpl withPrimaryPublicIPAddressDeleteOptions(DeleteOptions deleteOptions) {
this.ensureDeleteOptions(deleteOptions, "primary");
return this;
}

@Override
public NetworkInterfaceImpl update() {
this.specifiedIpConfigNames = new HashMap<String, DeleteOptions>();
return super.update();
}

public void ensureDeleteOptions(DeleteOptions deleteOptions, String ipConfigName) {
this.specifiedIpConfigNames.put(ipConfigName, deleteOptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.azure.resourcemanager.network.models.ApplicationGateway;
import com.azure.resourcemanager.network.models.ApplicationGatewayBackendAddressPool;
import com.azure.resourcemanager.network.models.ApplicationSecurityGroup;
import com.azure.resourcemanager.network.models.DeleteOptions;
import com.azure.resourcemanager.network.models.IpAllocationMethod;
import com.azure.resourcemanager.network.models.IpVersion;
import com.azure.resourcemanager.network.models.LoadBalancer;
Expand All @@ -28,6 +29,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/** Implementation for NicIPConfiguration and its create and update interfaces. */
Expand Down Expand Up @@ -257,11 +259,11 @@ private List<InboundNatRuleInner> ensureInboundNatRules() {
return natRefs;
}

protected static void ensureConfigurations(Collection<NicIpConfiguration> nicIPConfigurations) {
protected static void ensureConfigurations(Collection<NicIpConfiguration> nicIPConfigurations, Map<String, DeleteOptions> specifiedIpConfigNames) {
for (NicIpConfiguration nicIPConfiguration : nicIPConfigurations) {
NicIpConfigurationImpl config = (NicIpConfigurationImpl) nicIPConfiguration;
config.innerModel().withSubnet(config.subnetToAssociate());
config.innerModel().withPublicIpAddress(config.publicIPToAssociate());
config.innerModel().withPublicIpAddress(config.publicIPToAssociate(specifiedIpConfigNames.getOrDefault(config.name(), null)));
}
}

Expand Down Expand Up @@ -331,9 +333,10 @@ private SubnetInner subnetToAssociate() {
* public IP in create fluent chain. In case of update chain, if withoutPublicIP(..) is not specified then existing
* associated (if any) public IP will be returned.
*
* @param deleteOptions what happens to the public IP address when the VM using it is deleted
* @return public IP SubResource
*/
private PublicIpAddressInner publicIPToAssociate() {
private PublicIpAddressInner publicIPToAssociate(DeleteOptions deleteOptions) {
String pipId = null;
if (this.removePrimaryPublicIPAssociation) {
return null;
Expand All @@ -344,8 +347,14 @@ private PublicIpAddressInner publicIPToAssociate() {
}

if (pipId != null) {
if (Objects.nonNull(deleteOptions)) {
return new PublicIpAddressInner().withId(pipId).withDeleteOption(deleteOptions);
}
return new PublicIpAddressInner().withId(pipId);
} else if (!this.isInCreateMode) {
if (Objects.nonNull(this.innerModel().publicIpAddress()) && Objects.nonNull(deleteOptions)) {
return this.innerModel().publicIpAddress().withDeleteOption(deleteOptions);
}
return this.innerModel().publicIpAddress();
} else {
return null;
Expand Down Expand Up @@ -400,4 +409,10 @@ NicIpConfigurationImpl withoutApplicationSecurityGroup(String name) {
}
return this;
}

@Override
public NicIpConfigurationImpl withPublicIPAddressDeleteOptions(DeleteOptions deleteOptions) {
this.parent().ensureDeleteOptions(deleteOptions, this.innerModel().name());
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,17 @@ interface WithAcceleratedNetworking {
WithCreate withAcceleratedNetworking();
}

/** The stage of the definition allowing to specify delete options for the public ip address. */
interface WithPublicIPAddressDeleteOptions {
/**
* Sets delete options for public ip address.
*
* @param deleteOptions the delete options for primary network interfaces
* @return the next stage of the update
*/
WithCreate withPrimaryPublicIPAddressDeleteOptions(DeleteOptions deleteOptions);
}

/**
* The stage of the network interface definition which contains all the minimum required inputs for the resource
* to be created, but also allows for any other optional settings to be specified.
Expand All @@ -268,7 +279,8 @@ interface WithCreate
WithSecondaryIPConfiguration,
WithAcceleratedNetworking,
WithLoadBalancer,
WithApplicationSecurityGroup {
WithApplicationSecurityGroup,
WithPublicIPAddressDeleteOptions {
/**
* Enables IP forwarding in the network interface.
*
Expand Down Expand Up @@ -576,6 +588,18 @@ interface WithLoadBalancer {
*/
Update withoutLoadBalancerInboundNatRules();
}

/** The stage of the network interface update allowing to specify delete options for the public ip address. */
interface WithPublicIPAddressDeleteOptions {

/**
* Sets delete options for public ip address.
*
* @param deleteOptions the delete options for primary network interfaces
* @return the next stage of the update
*/
Update withPrimaryPublicIPAddressDeleteOptions(DeleteOptions deleteOptions);
}
}

/** The template for an update operation, containing all the settings that can be modified. */
Expand All @@ -591,6 +615,7 @@ interface Update
UpdateStages.WithIPConfiguration,
UpdateStages.WithLoadBalancer,
UpdateStages.WithAcceleratedNetworking,
UpdateStages.WithApplicationSecurityGroup {
UpdateStages.WithApplicationSecurityGroup,
UpdateStages.WithPublicIPAddressDeleteOptions {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@ WithAttach<ParentT> withExistingApplicationGatewayBackend(
ApplicationGateway appGateway, String backendName);
}


/** The stage of the definition allowing to specify delete options for the public ip address.
*
* @param <ParentT> the stage of the parent network interface definition to return to after attaching this
* definition
* */
interface WithPublicIPAddressDeleteOptions<ParentT> {
/**
* Sets delete options for public ip address.
*
* @param deleteOptions the delete options for primary network interfaces
* @return the next stage of the definition
*/
WithAttach<ParentT> withPublicIPAddressDeleteOptions(DeleteOptions deleteOptions);
}

/**
* The final stage of network interface IP configuration.
*
Expand All @@ -201,7 +217,8 @@ interface WithAttach<ParentT>
extends Attachable.InDefinition<ParentT>,
WithPublicIPAddress<ParentT>,
WithLoadBalancer<ParentT>,
WithApplicationGateway<ParentT> {
WithApplicationGateway<ParentT>,
WithPublicIPAddressDeleteOptions<ParentT> {
}
}

Expand Down Expand Up @@ -372,6 +389,22 @@ WithAttach<ParentT> withExistingApplicationGatewayBackend(
ApplicationGateway appGateway, String backendName);
}

/**
* The stage of the definition allowing to specify delete options for the public ip address.
*
* @param <ParentT> the stage of the parent network interface update to return to after attaching this
* definition
* */
interface WithPublicIPAddressDeleteOptions<ParentT> {
/**
* Sets delete options for public ip address.
*
* @param deleteOptions the delete options for primary network interfaces
* @return the next stage of the update
*/
WithAttach<ParentT> withPublicIPAddressDeleteOptions(DeleteOptions deleteOptions);
}

/**
* The final stage of network interface IP configuration.
*
Expand All @@ -385,7 +418,8 @@ interface WithAttach<ParentT>
extends Attachable.InUpdate<ParentT>,
WithPublicIPAddress<ParentT>,
WithLoadBalancer<ParentT>,
WithApplicationGateway<ParentT> {
WithApplicationGateway<ParentT>,
WithPublicIPAddressDeleteOptions<ParentT> {
}
}

Expand All @@ -396,7 +430,8 @@ interface Update
UpdateStages.WithPrivateIP,
UpdateStages.WithPublicIPAddress,
UpdateStages.WithLoadBalancer,
UpdateStages.WithApplicationGateway {
UpdateStages.WithApplicationGateway,
UpdateStages.WithPublicIPAddressDeleteOptions {
}

/** Grouping of network interface IP configuration update stages. */
Expand Down Expand Up @@ -486,5 +521,16 @@ interface WithApplicationGateway {
*/
Update withoutApplicationGatewayBackends();
}

/** The stage of the network interface update allowing to specify delete options for the public ip address. */
interface WithPublicIPAddressDeleteOptions {
/**
* Sets delete options for public ip address.
*
* @param deleteOptions the delete options for primary network interfaces
* @return the next stage of the update
*/
Update withPublicIPAddressDeleteOptions(DeleteOptions deleteOptions);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.azure.core.management.Region;
import com.azure.resourcemanager.network.fluent.models.NatGatewayInner;
import com.azure.resourcemanager.network.models.ApplicationSecurityGroup;
import com.azure.resourcemanager.network.models.DeleteOptions;
import com.azure.resourcemanager.network.models.NatGatewaySku;
import com.azure.resourcemanager.network.models.NatGatewaySkuName;
import com.azure.resourcemanager.network.models.Network;
Expand Down Expand Up @@ -509,6 +510,80 @@ public void canAssociateNatGateway() {
Assertions.assertEquals(gateway2.id(), subnet2.natGatewayId());
}

@Test
public void canCreateAndUpdateNicWithMultipleDeleteOptions() {
String subnetName = generateRandomResourceName("subnet-", 15);
resourceManager.resourceGroups().define(rgName).withRegion(Region.US_EAST).create();
Network vnet = networkManager.networks()
.define(generateRandomResourceName("vnet-", 15))
.withRegion(Region.US_EAST)
.withExistingResourceGroup(rgName)
.withAddressSpace("10.0.0.0/28")
.withSubnet(subnetName, "10.0.0.0/28")
.create();

NetworkInterface nic = networkManager.networkInterfaces()
.define(generateRandomResourceName("nic-", 15))
.withRegion(Region.US_EAST)
.withExistingResourceGroup(rgName)
.withExistingPrimaryNetwork(vnet)
.withSubnet(subnetName)
.withPrimaryPrivateIPAddressDynamic()
.withNewPrimaryPublicIPAddress()
.withPrimaryPublicIPAddressDeleteOptions(DeleteOptions.DELETE)
.defineSecondaryIPConfiguration("secondary1")
.withExistingNetwork(vnet)
.withSubnet(subnetName)
.withPrivateIpAddressDynamic()
.withNewPublicIpAddress()
.withPublicIPAddressDeleteOptions(DeleteOptions.DETACH)
.attach()
.defineSecondaryIPConfiguration("secondary2")
.withExistingNetwork(vnet)
.withSubnet(subnetName)
.withPrivateIpAddressDynamic()
.withNewPublicIpAddress()
.withPublicIPAddressDeleteOptions(DeleteOptions.DETACH)
.attach()
.create();

nic.refresh();
Assertions.assertEquals(DeleteOptions.DELETE, nic.primaryIPConfiguration().innerModel().publicIpAddress().deleteOption());
Assertions.assertEquals(DeleteOptions.DETACH, nic.ipConfigurations().get("secondary1").innerModel().publicIpAddress().deleteOption());
Assertions.assertEquals(DeleteOptions.DETACH, nic.ipConfigurations().get("secondary2").innerModel().publicIpAddress().deleteOption());

String existingPrimaryIpAddressId = nic.primaryIPConfiguration().publicIpAddressId();
nic.update().withNewPrimaryPublicIPAddress().withPrimaryPublicIPAddressDeleteOptions(DeleteOptions.DETACH).apply();
nic.refresh();
Assertions.assertFalse(existingPrimaryIpAddressId.equalsIgnoreCase(nic.primaryIPConfiguration().publicIpAddressId()));
Assertions.assertEquals(DeleteOptions.DETACH, nic.primaryIPConfiguration().innerModel().publicIpAddress().deleteOption());

String existingSecondary1IpAddressId = nic.ipConfigurations().get("secondary1").publicIpAddressId();
nic.update()
.withPrimaryPublicIPAddressDeleteOptions(DeleteOptions.DELETE)
.updateIPConfiguration("secondary1")
.withNewPublicIpAddress()
.withPublicIPAddressDeleteOptions(DeleteOptions.DELETE)
.parent()
.updateIPConfiguration("secondary2")
.withPublicIPAddressDeleteOptions(DeleteOptions.DELETE)
.parent()
.defineSecondaryIPConfiguration("secondary3")
.withExistingNetwork(vnet)
.withSubnet(subnetName)
.withPrivateIpAddressDynamic()
.withNewPublicIpAddress()
.withPublicIPAddressDeleteOptions(DeleteOptions.DELETE)
.attach()
.apply();
nic.refresh();
Assertions.assertFalse(existingSecondary1IpAddressId.equalsIgnoreCase(nic.ipConfigurations().get("secondary1").publicIpAddressId()));
Assertions.assertEquals(DeleteOptions.DELETE, nic.primaryIPConfiguration().innerModel().publicIpAddress().deleteOption());
Assertions.assertEquals(DeleteOptions.DELETE, nic.ipConfigurations().get("secondary1").innerModel().publicIpAddress().deleteOption());
Assertions.assertEquals(DeleteOptions.DELETE, nic.ipConfigurations().get("secondary2").innerModel().publicIpAddress().deleteOption());
Assertions.assertEquals(DeleteOptions.DELETE, nic.ipConfigurations().get("secondary3").innerModel().publicIpAddress().deleteOption());
}

private NatGatewayInner createNatGateway() {
String natGatewayName = generateRandomResourceName("natgw", 10);
return networkManager.serviceClient()
Expand Down

0 comments on commit 38cf774

Please sign in to comment.