Skip to content

Commit

Permalink
Add operator-sdk runner (#153)
Browse files Browse the repository at this point in the history
## Description

Closes #152

## Type of Change

* New feature (non-breaking change which adds functionality)

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit/integration tests pass locally with my
changes

Signed-off-by: Jakub Stejskal <[email protected]>
  • Loading branch information
Frawless authored Jul 29, 2024
1 parent 554c4bf commit 2bd6b08
Show file tree
Hide file tree
Showing 5 changed files with 364 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@
<artifactId>test-frame-kubernetes</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.skodjob</groupId>
<artifactId>test-frame-openshift</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.skodjob</groupId>
<artifactId>test-frame-log-collector</artifactId>
Expand Down
14 changes: 14 additions & 0 deletions test-frame-openshift/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright Skodjob authors.
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
*/
package io.skodjob.testframe.olm;

import io.skodjob.testframe.executor.Exec;
import io.skodjob.testframe.executor.ExecResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* Runner for operator-sdk run command
*/
public class OperatorSdkRun {
private static final Logger LOGGER = LoggerFactory.getLogger(OperatorSdkRun.class);

protected String namespace;
protected String timeout;
protected String installMode;
protected String indexImage;
protected String kubeconfig;
protected String bundleImage;

private static final String OPTION_INDEX_IMAGE = "--index-image";
private static final String OPTION_NAMESPACE = "--namespace";
private static final String OPTION_KUBECONFIG = "--kubeconfig";
private static final String OPTION_TIMEOUT = "--timeout";
private static final String OPTION_INSTALL_MODE = "--install-mode";
private static final String CMD = "operator-sdk";
private static final String RUN = "run";
private static final String BUNDLE = "bundle";

/**
* Constructor of the runner
*
* @param operatorSdkRunBuilder operator-sdk run command configuration
*/
public OperatorSdkRun(OperatorSdkRunBuilder operatorSdkRunBuilder) {
if (operatorSdkRunBuilder.getNamespace() == null) {
throw new InvalidParameterException("Namespace is a mandatory parameter for OperatorSdkRun!");
}

if (operatorSdkRunBuilder.getBundleImage() == null) {
throw new InvalidParameterException("BundleImage is a mandatory parameter for OperatorSdkRun!");
}

if (operatorSdkRunBuilder.getInstallMode() == null) {
throw new InvalidParameterException("InstallMode is a mandatory parameter for OperatorSdkRun!");
}

this.namespace = operatorSdkRunBuilder.getNamespace();
this.bundleImage = operatorSdkRunBuilder.getBundleImage();
this.installMode = operatorSdkRunBuilder.getInstallMode();
this.timeout = operatorSdkRunBuilder.getTimeout();
this.indexImage = operatorSdkRunBuilder.getIndexImage();
this.kubeconfig = operatorSdkRunBuilder.getKubeconfig();
}

/**
* Run the built command via Executor and return it result
*
* @return ExecResult with data from the executor
*/
public ExecResult run() {
List<String> command = new ArrayList<>(Arrays.asList(CMD, RUN, BUNDLE, bundleImage));

command.add(OPTION_NAMESPACE);
command.add(namespace);
command.add(OPTION_INSTALL_MODE);
command.add(installMode);

if (indexImage != null) {
command.add(OPTION_INDEX_IMAGE);
command.add(indexImage);
}

if (timeout != null) {
command.add(OPTION_TIMEOUT);
command.add(String.valueOf(timeout));
}

if (kubeconfig != null) {
command.add(OPTION_KUBECONFIG);
command.add(kubeconfig);
}

return Exec.exec(command);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* Copyright Skodjob authors.
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
*/
package io.skodjob.testframe.olm;

/**
* Builder class for the {@link OperatorSdkRun}
*/
public class OperatorSdkRunBuilder {

private String namespace;
private String timeout;
private String installMode;
private String indexImage;
private String kubeconfig;
private String bundleImage;


/**
* Constructor for creating {@link OperatorSdkRunBuilder} with parameters from
* current instance of {@link OperatorSdkRun}.
*
* @param operatorSdkRun current instance of {@link OperatorSdkRun}
*/
public OperatorSdkRunBuilder(OperatorSdkRun operatorSdkRun) {
this.namespace = operatorSdkRun.namespace;
this.timeout = operatorSdkRun.timeout;
this.installMode = operatorSdkRun.installMode;
this.indexImage = operatorSdkRun.indexImage;
this.kubeconfig = operatorSdkRun.kubeconfig;
this.bundleImage = operatorSdkRun.bundleImage;
}

/**
* Empty constructor, we can use the "with" methods to build the LogCollector's configuration
*/
public OperatorSdkRunBuilder() {
// empty constructor
}

/**
* Method for setting the namespace, where the bundle container will be deployed
*
* @param namespace where the bundle container will be deployed
* @return {@link OperatorSdkRunBuilder} object
*/
public OperatorSdkRunBuilder withNamespace(String namespace) {
this.namespace = namespace;
return this;
}

/**
* Method for setting the timeout - string dictating the maximum time that run can run.
* The command will return an error if the timeout is exceeded.
*
* @param timeout string dictating the maximum time that run
* @return {@link OperatorSdkRunBuilder} object
*/
public OperatorSdkRunBuilder withTimeout(String timeout) {
this.timeout = timeout;
return this;
}

/**
* Method for setting the index-image for run command
*
* @param indexImage specifies an index image in which to inject the given bundle
* @return {@link OperatorSdkRunBuilder} object
*/
public OperatorSdkRunBuilder withIndexImage(String indexImage) {
this.indexImage = indexImage;
return this;
}

/**
* Method for setting the install-mode for run command
*
* @param installMode (AllNamespace|OwnNamespace|SingleNamespace=)
* @return {@link OperatorSdkRunBuilder} object
*/
public OperatorSdkRunBuilder withInstallMode(String installMode) {
this.installMode = installMode;
return this;
}

/**
* Method for setting the kubeconfig for run command
*
* @param kubeconfig the local path to a kubeconfig
* @return {@link OperatorSdkRunBuilder} object
*/
public OperatorSdkRunBuilder withKubeConfig(String kubeconfig) {
this.kubeconfig = kubeconfig;
return this;
}

/**
* Method for setting the bundle-image for run command
*
* @param bundleImage specifies the Operator bundle image
* @return {@link OperatorSdkRunBuilder} object
*/
public OperatorSdkRunBuilder withBundleImage(String bundleImage) {
this.bundleImage = bundleImage;
return this;
}

/**
* Get namespace
*
* @return namespace
*/
public String getNamespace() {
return namespace;
}

/**
* Get timeout
*
* @return timeout
*/
public String getTimeout() {
return timeout;
}

/**
* Get installMode
*
* @return installMode
*/
public String getInstallMode() {
return installMode;
}

/**
* Get indexImage
*
* @return indexImage
*/
public String getIndexImage() {
return indexImage;
}

/**
* Get kubeconfig
*
* @return kubeconfig
*/
public String getKubeconfig() {
return kubeconfig;
}

/**
* Get bundleImage
*
* @return bundleImage
*/
public String getBundleImage() {
return bundleImage;
}

/**
* Method for building the {@link OperatorSdkRun} object
*
* @return {@link OperatorSdkRun} configured by the specified parameters
*/
public OperatorSdkRun build() {
return new OperatorSdkRun(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Skodjob authors.
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
*/
package io.skodjob.testframe.olm;

import org.junit.jupiter.api.Test;

import java.security.InvalidParameterException;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class OperatorSdkRunBuilderTest {

@Test
void testBuilder() {
OperatorSdkRun operatorSdkRun = new OperatorSdkRunBuilder()
.withTimeout("2m")
.withNamespace("namespace-1")
.withBundleImage("my-bundle-image")
.withIndexImage("my-index-image")
.withKubeConfig("path-to-kubeconfig")
.withInstallMode("automatic")
.build();

assertNotNull(operatorSdkRun);

assertEquals(operatorSdkRun.bundleImage, "my-bundle-image");
assertEquals(operatorSdkRun.timeout, "2m");
assertEquals(operatorSdkRun.indexImage, "my-index-image");
assertEquals(operatorSdkRun.namespace, "namespace-1");
assertEquals(operatorSdkRun.installMode, "automatic");
assertEquals(operatorSdkRun.kubeconfig, "path-to-kubeconfig");
}

@Test
void testMissingNamespace() {
OperatorSdkRunBuilder operatorSdkRunBuilder = new OperatorSdkRunBuilder()
.withTimeout("2m")
.withBundleImage("my-bundle-image")
.withIndexImage("my-index-image")
.withKubeConfig("path-to-kubeconfig")
.withInstallMode("automatic");

InvalidParameterException thrown = assertThrows(InvalidParameterException.class, operatorSdkRunBuilder::build);

assertEquals("Namespace is a mandatory parameter for OperatorSdkRun!", thrown.getMessage());
}

@Test
void testMissingBundleImage() {
OperatorSdkRunBuilder operatorSdkRunBuilder = new OperatorSdkRunBuilder()
.withTimeout("2m")
.withNamespace("namespace-1")
.withIndexImage("my-index-image")
.withKubeConfig("path-to-kubeconfig")
.withInstallMode("automatic");

InvalidParameterException thrown = assertThrows(InvalidParameterException.class, operatorSdkRunBuilder::build);

assertEquals("BundleImage is a mandatory parameter for OperatorSdkRun!", thrown.getMessage());
}

@Test
void testWrongInstallMode() {
OperatorSdkRunBuilder operatorSdkRunBuilder = new OperatorSdkRunBuilder()
.withTimeout("2m")
.withNamespace("namespace-1")
.withIndexImage("my-index-image")
.withBundleImage("my-bundle-image")
.withKubeConfig("path-to-kubeconfig");

InvalidParameterException thrown = assertThrows(InvalidParameterException.class, operatorSdkRunBuilder::build);

assertEquals("InstallMode is a mandatory parameter for OperatorSdkRun!", thrown.getMessage());
}
}

0 comments on commit 2bd6b08

Please sign in to comment.