Skip to content

owls-87625 - Remove stranded old named node port service for the domain when deleting and replacing service #2208

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

Merged
merged 4 commits into from
Feb 23, 2021
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 @@ -4,16 +4,19 @@
package oracle.kubernetes.operator.helpers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;

import io.kubernetes.client.openapi.models.V1DeleteOptions;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
import io.kubernetes.client.openapi.models.V1Service;
import io.kubernetes.client.openapi.models.V1ServiceList;
import io.kubernetes.client.openapi.models.V1ServicePort;
import io.kubernetes.client.openapi.models.V1ServiceSpec;
import io.kubernetes.client.openapi.models.V1Status;
Expand All @@ -24,7 +27,9 @@
import oracle.kubernetes.operator.calls.UnrecoverableErrorBuilder;
import oracle.kubernetes.operator.logging.LoggingFacade;
import oracle.kubernetes.operator.logging.LoggingFactory;
import oracle.kubernetes.operator.steps.ActionResponseStep;
import oracle.kubernetes.operator.steps.DefaultResponseStep;
import oracle.kubernetes.operator.steps.DeleteServiceListStep;
import oracle.kubernetes.operator.wlsconfig.NetworkAccessPoint;
import oracle.kubernetes.operator.wlsconfig.WlsClusterConfig;
import oracle.kubernetes.operator.wlsconfig.WlsDomainConfig;
Expand All @@ -40,7 +45,10 @@
import oracle.kubernetes.weblogic.domain.model.ServerSpec;
import org.apache.commons.lang3.builder.EqualsBuilder;

import static oracle.kubernetes.operator.LabelConstants.forDomainUidSelector;
import static oracle.kubernetes.operator.LabelConstants.getCreatedbyOperatorSelector;
import static oracle.kubernetes.operator.helpers.KubernetesUtils.getDomainUidLabel;
import static oracle.kubernetes.operator.helpers.OperatorServiceType.EXTERNAL;
import static oracle.kubernetes.operator.logging.MessageKeys.ADMIN_SERVICE_CREATED;
import static oracle.kubernetes.operator.logging.MessageKeys.ADMIN_SERVICE_EXISTS;
import static oracle.kubernetes.operator.logging.MessageKeys.ADMIN_SERVICE_REPLACED;
Expand Down Expand Up @@ -527,10 +535,29 @@ private Step createNewService(Step next) {
protected abstract String getServiceCreatedMessageKey();

private Step deleteAndReplaceService(Step next) {
V1DeleteOptions deleteOptions = new V1DeleteOptions();
if (serviceType == EXTERNAL) {
return deleteAndReplaceNodePortService();
} else {
V1DeleteOptions deleteOptions = new V1DeleteOptions();
return new CallBuilder()
.deleteServiceAsync(
createServiceName(), getNamespace(), getDomainUid(), deleteOptions, new DeleteServiceResponse(next));
}
}

private Step deleteAndReplaceNodePortService() {
return new CallBuilder()
.deleteServiceAsync(
createServiceName(), getNamespace(), getDomainUid(), deleteOptions, new DeleteServiceResponse(next));
.withLabelSelectors(forDomainUidSelector(info.getDomainUid()), getCreatedbyOperatorSelector())
.listServiceAsync(
getNamespace(),
new ActionResponseStep<V1ServiceList>() {
public Step createSuccessStep(V1ServiceList result, Step next) {
Collection<V1Service> c = Optional.ofNullable(result).map(list -> list.getItems().stream()
.filter(s -> isNodePortType(s))
.collect(Collectors.toList())).orElse(new ArrayList<>());
return new DeleteServiceListStep(c, createReplacementService(next));
}
});
}

private Step createReplacementService(Step next) {
Expand Down Expand Up @@ -798,7 +825,7 @@ private static class ExternalServiceStepContext extends ServiceStepContext {
private final String adminServerName;

ExternalServiceStepContext(Step conflictStep, Packet packet) {
super(conflictStep, packet, OperatorServiceType.EXTERNAL);
super(conflictStep, packet, EXTERNAL);
adminServerName = (String) packet.get(ProcessingConstants.SERVER_NAME);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*/
public class DeleteServiceListStep extends AbstractListStep<V1Service> {

DeleteServiceListStep(Collection<V1Service> c, Step next) {
public DeleteServiceListStep(Collection<V1Service> c, Step next) {
super(c, next);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
import javax.annotation.Nonnull;

import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
import io.kubernetes.client.openapi.models.V1OwnerReference;
import io.kubernetes.client.openapi.models.V1Service;
import io.kubernetes.client.openapi.models.V1ServicePort;
import io.kubernetes.client.openapi.models.V1ServiceSpec;
import oracle.kubernetes.operator.KubernetesConstants;
import oracle.kubernetes.operator.LabelConstants;
import oracle.kubernetes.operator.calls.FailureStatusSourceException;
Expand Down Expand Up @@ -76,6 +78,7 @@
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;
Expand Down Expand Up @@ -121,6 +124,8 @@ public class ServiceHelperTest extends ServiceHelperTestBase {
private static final int NAP_PORT_1 = 7100;
private static final int NAP_PORT_2 = 37100;
private static final int NAP_PORT_3 = 37200;
public static final String STRANDED = "Stranded";
public static final String NODE_PORT = "NodePort";
private final TerminalStep terminalStep = new TerminalStep();
@Parameter public String testType;
@Parameter(1)
Expand Down Expand Up @@ -399,11 +404,20 @@ public void whenConfiguredSslListenPortChanged_replaceService() {

private void verifyServiceReplaced(Runnable configurationMutator) {
recordInitialService();
if (testFacade instanceof ExternalServiceTestFacade) {
recordStrandedService();
}
configurationMutator.run();

runServiceHelper();

assertThat(logRecords, containsInfo(testFacade.getServiceReplacedLogMessage()));
assertThat(getStrandedService(), empty());
}

private List<Object> getStrandedService() {
ArrayList<V1Service> svcList = (ArrayList)testSupport.getResources(SERVICE);
return svcList.stream().filter(s -> s.getMetadata().getName().equals(STRANDED)).collect(Collectors.toList());
}

private void configureNewLabel() {
Expand Down Expand Up @@ -436,6 +450,16 @@ private void recordInitialService() {
testFacade.recordService(domainPresenceInfo, originalService);
}

private void recordStrandedService() {
Map<String, String> labels = new HashMap<>();
labels.put(LabelConstants.DOMAINUID_LABEL, UID);
labels.put(LabelConstants.CREATEDBYOPERATOR_LABEL, "true");
V1Service strandedService = new V1Service().metadata(new V1ObjectMeta().name(STRANDED).namespace(NS)
.labels(labels)).spec(new V1ServiceSpec().type(NODE_PORT));
testSupport.defineResources(strandedService);
testFacade.recordService(domainPresenceInfo, strandedService);
}

@Test
public void whenServiceLabelAdded_dontReplaceService() {
verifyServiceNotReplaced(this::addNewLabel);
Expand Down