Skip to content

Commit

Permalink
mgmt, aks avoid unnecessary PUT (#28123)
Browse files Browse the repository at this point in the history
  • Loading branch information
weidongxu-microsoft authored Apr 11, 2022
1 parent 3070bf2 commit 9f73a2e
Show file tree
Hide file tree
Showing 12 changed files with 2,556 additions and 2,047 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
- Supported disabling local accounts for `KubernetesCluster`.
- Supported disk encryption set for `KubernetesCluster`.

### Bugs Fixed

- Fixed a bug that `orchestratorVersion` not initialized in agent pool.

### Other Changes

- Changed behavior that `KubernetesCluster` no longer retrieves admin and user KubeConfig during create, update, refresh.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,50 @@ public Map<String, String> tags() {
: Collections.unmodifiableMap(innerModel().tags());
}

// @Override
// public void start() {
// startAsync().block();
// }
//
// @Override
// public Mono<Void> startAsync() {
// AgentPoolInner innerModel = this.getAgentPoolInner();
// PowerState powerState = innerModel.powerState();
// if (powerState == null) {
// powerState = new PowerState();
// innerModel.withPowerState(powerState);
// }
// powerState.withCode(Code.RUNNING);
// return parent().manager().serviceClient().getAgentPools()
// .createOrUpdateAsync(parent().resourceGroupName(), parent().name(), this.name(), innerModel)
// .map(inner -> {
// this.innerModel().withPowerState(inner.powerState());
// return inner;
// }).then();
// }
//
// @Override
// public void stop() {
// stopAsync().block();
// }
//
// @Override
// public Mono<Void> stopAsync() {
// AgentPoolInner innerModel = this.getAgentPoolInner();
// PowerState powerState = innerModel.powerState();
// if (powerState == null) {
// powerState = new PowerState();
// innerModel.withPowerState(powerState);
// }
// powerState.withCode(Code.STOPPED);
// return parent().manager().serviceClient().getAgentPools()
// .createOrUpdateAsync(parent().resourceGroupName(), parent().name(), this.name(), innerModel)
// .map(inner -> {
// this.innerModel().withPowerState(inner.powerState());
// return inner;
// }).then();
// }

@Override
public KubernetesClusterAgentPoolImpl withVirtualMachineSize(ContainerServiceVMSizeTypes vmSize) {
this.innerModel().withVmSize(vmSize.toString());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.resourcemanager.containerservice.implementation;

import com.azure.core.http.rest.PagedFlux;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.http.rest.Response;
import com.azure.core.http.rest.SimpleResponse;
import com.azure.core.management.serializer.SerializerFactory;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.serializer.SerializerAdapter;
import com.azure.core.util.serializer.SerializerEncoding;
import com.azure.resourcemanager.containerservice.ContainerServiceManager;
import com.azure.resourcemanager.containerservice.fluent.models.ManagedClusterInner;
import com.azure.resourcemanager.containerservice.fluent.models.PrivateEndpointConnectionInner;
Expand Down Expand Up @@ -39,11 +43,13 @@
import com.azure.resourcemanager.resources.fluentcore.utils.ResourceManagerUtils;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

Expand All @@ -58,6 +64,10 @@ public class KubernetesClusterImpl
private List<CredentialResult> userKubeConfigs;
private final Map<Format, List<CredentialResult>> formatUserKubeConfigsMap = new ConcurrentHashMap<>();

private ManagedClusterInner parameterSnapshotOnUpdate;
private static final SerializerAdapter SERIALIZER_ADAPTER =
SerializerFactory.createDefaultManagementSerializerAdapter();

protected KubernetesClusterImpl(String name, ManagedClusterInner innerObject, ContainerServiceManager manager) {
super(name, innerObject, manager);
if (this.innerModel().agentPoolProfiles() == null) {
Expand Down Expand Up @@ -300,23 +310,96 @@ protected Mono<ManagedClusterInner> getInnerAsync() {
});
}

@Override
public KubernetesClusterImpl update() {
parameterSnapshotOnUpdate = this.deepCopyInner();
parameterSnapshotOnUpdate.withServicePrincipalProfile(null); // servicePrincipalProfile is null in update
return super.update();
}

boolean isClusterModifiedDuringUpdate(ManagedClusterInner parameter) {
if (parameterSnapshotOnUpdate == null || parameter == null) {
return true;
} else {
final List<ManagedClusterAgentPoolProfile> parameterSnapshotAgentPools =
parameterSnapshotOnUpdate.agentPoolProfiles();
final List<ManagedClusterAgentPoolProfile> parameterAgentPools = parameter.agentPoolProfiles();

// intersection of agent pool names
Set<String> intersectAgentPoolNames = parameter.agentPoolProfiles().stream()
.map(ManagedClusterAgentPoolProfile::name)
.collect(Collectors.toSet());
intersectAgentPoolNames.retainAll(parameterSnapshotOnUpdate.agentPoolProfiles().stream()
.map(ManagedClusterAgentPoolProfile::name)
.collect(Collectors.toSet()));

// compare the intersection, as add/delete is handled by REST API on AgentPoolsClient
List<ManagedClusterAgentPoolProfile> agentPools = parameterSnapshotOnUpdate.agentPoolProfiles()
.stream()
.filter(p -> intersectAgentPoolNames.contains(p.name()))
.collect(Collectors.toList());
// will be reverted in finally block
parameterSnapshotOnUpdate.withAgentPoolProfiles(agentPools);

agentPools = parameter.agentPoolProfiles()
.stream()
.filter(p -> intersectAgentPoolNames.contains(p.name()))
.collect(Collectors.toList());
// will be reverted in finally block
parameter.withAgentPoolProfiles(agentPools);

try {
String jsonStrSnapshot =
SERIALIZER_ADAPTER.serialize(parameterSnapshotOnUpdate, SerializerEncoding.JSON);
String jsonStr = SERIALIZER_ADAPTER.serialize(parameter, SerializerEncoding.JSON);
return !jsonStr.equals(jsonStrSnapshot);
} catch (IOException e) {
// ignored, treat as modified
return true;
} finally {
parameterSnapshotOnUpdate.withAgentPoolProfiles(parameterSnapshotAgentPools);
parameter.withAgentPoolProfiles(parameterAgentPools);
}
}
}

ManagedClusterInner deepCopyInner() {
ManagedClusterInner updateParameter;
try {
// deep copy via json
String jsonStr = SERIALIZER_ADAPTER.serialize(this.innerModel(), SerializerEncoding.JSON);
updateParameter =
SERIALIZER_ADAPTER.deserialize(jsonStr, ManagedClusterInner.class, SerializerEncoding.JSON);
} catch (IOException e) {
// ignored, null to signify not available
updateParameter = null;
}
return updateParameter;
}

@Override
public Mono<KubernetesCluster> createResourceAsync() {
final KubernetesClusterImpl self = this;
if (!this.isInCreateMode()) {
this.innerModel().withServicePrincipalProfile(null);
}

return this
.manager()
.serviceClient()
.getManagedClusters()
.createOrUpdateAsync(self.resourceGroupName(), self.name(), self.innerModel())
.map(inner -> {
self.setInner(inner);
clearKubeConfig();
return self;
});
final boolean createOrModified = this.isInCreateMode() || this.isClusterModifiedDuringUpdate(this.innerModel());

if (createOrModified) {
return this
.manager()
.serviceClient()
.getManagedClusters()
.createOrUpdateAsync(self.resourceGroupName(), self.name(), self.innerModel())
.map(inner -> {
self.setInner(inner);
clearKubeConfig();
return self;
});
} else {
return Mono.just(this);
}
}

private void clearKubeConfig() {
Expand Down Expand Up @@ -387,8 +470,9 @@ public KubernetesClusterImpl withDnsPrefix(String dnsPrefix) {

@Override
public KubernetesClusterAgentPoolImpl defineAgentPool(String name) {
ManagedClusterAgentPoolProfile innerPoolProfile = new ManagedClusterAgentPoolProfile();
innerPoolProfile.withName(name);
ManagedClusterAgentPoolProfile innerPoolProfile = new ManagedClusterAgentPoolProfile()
.withName(name)
.withOrchestratorVersion(this.innerModel().kubernetesVersion());
return new KubernetesClusterAgentPoolImpl(innerPoolProfile, this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,30 @@ public interface KubernetesClusterAgentPool
*/
Map<String, String> tags();

// /**
// * Starts the agent pool.
// */
// void start();
//
// /**
// * Starts the agent pool.
// *
// * @return A {@link Mono} that completes when a successful response is received.
// */
// Mono<Void> startAsync();
//
// /**
// * Stops the agent pool.
// */
// void stop();
//
// /**
// * Stops the agent pool.
// *
// * @return A {@link Mono} that completes when a successful response is received.
// */
// Mono<Void> stopAsync();

// Fluent interfaces

/**
Expand Down
Loading

0 comments on commit 9f73a2e

Please sign in to comment.