Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DeleteOptions on Public Ip Address (issue#38806) #39096

Merged
merged 12 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Features Added

- Supported set `DeleteOptions` on a public IP address in `NetworkInterface`, for allow deleting the public IP automatically when the virtual machine is deleted.
v-hongli1 marked this conversation as resolved.
Show resolved Hide resolved

### 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) {
v-hongli1 marked this conversation as resolved.
Show resolved Hide resolved
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();
v-hongli1 marked this conversation as resolved.
Show resolved Hide resolved

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();
v-hongli1 marked this conversation as resolved.
Show resolved Hide resolved
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)
v-hongli1 marked this conversation as resolved.
Show resolved Hide resolved
.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
Loading