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

mgmt, AKS avoid unnecessary PUT #28123

Merged
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -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) {
XiaofeiCao marked this conversation as resolved.
Show resolved Hide resolved
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