Skip to content

Commit

Permalink
feat: support basic registry authentication (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleksii-Klimov authored Dec 11, 2024
1 parent c36229b commit 6218876
Show file tree
Hide file tree
Showing 14 changed files with 569 additions and 457 deletions.
41 changes: 22 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,28 @@ The application can be configured using environment variables or by modifying th

### Environment Variables

| Setting | Default | Required | Description |
|---------------------------------|--------------------------------------------------|------------|--------------------------------------------------------------|
| `APP_DOCKER_REGISTRY` | | Yes | The Docker registry where images are stored. |
| `APP_DIAL_BASE_URL` | | Yes | The base URL for the DIAL service. |
| `APP_DEPLOY_NAMESPACE` | `default` | No | The Kubernetes namespace used for deploying services. |
| `APP_BUILD_NAMESPACE` | `default` | No | The Kubernetes namespace used for building images. |
| `APP_HEARTBEAT_PERIOD_SEC` | `30` | No | The interval in seconds for sending heartbeat events. |
| `APP_IMAGE_NAME_FORMAT` | `app-%s` | No | Format for naming Docker images. |
| `APP_IMAGE_LABEL` | `latest` | No | The label used for Docker images. |
| `APP_IMAGE_BUILD_TIMEOUT_SEC` | `300` | No | Timeout in seconds for building Docker images. |
| `APP_SERVICE_SETUP_TIMEOUT_SEC` | `300` | No | Timeout in seconds for setting up Knative services. |
| `APP_MAX_ERROR_LOG_LINES` | `20` | No | Maximum number of error log lines to return in message. |
| `APP_MAX_ERROR_LOG_CHARS` | `1000` | No | Maximum number of error log characters to return in message. |
| `APP_TEMPLATE_IMAGE` | `${app.docker-registry}/builder-template:latest` | No | The Docker image used as the template for building. |
| `APP_BUILDER_IMAGE` | `gcr.io/kaniko-project/executor:latest` | No | The Docker image used for building applications. |
| `APP_TEMPLATE_CONTAINER` | `template` | No | Name of the template container in Kubernetes job. |
| `APP_BUILDER_CONTAINER` | `builder` | No | Name of the builder container in Kubernetes job. |
| `APP_SERVICE_CONTAINER` | `app-container` | No | Name of the service container. |
| `APP_DEFAULT_RUNTIME` | `python3.11` | No | Default runtime for Python applications. |
| Setting | Default | Required | Description |
|---------------------------------|--------------------------------------------------|--------------|--------------------------------------------------------------|
| `APP_DOCKER_REGISTRY` | | Yes | The Docker registry where images are stored. |
| `APP_DIAL_BASE_URL` | | Yes | The base URL for the DIAL service. |
| `APP_DEPLOY_NAMESPACE` | `default` | No | The Kubernetes namespace used for deploying services. |
| `APP_BUILD_NAMESPACE` | `default` | No | The Kubernetes namespace used for building images. |
| `APP_HEARTBEAT_PERIOD_SEC` | `30` | No | The interval in seconds for sending heartbeat events. |
| `APP_IMAGE_NAME_FORMAT` | `app-%s` | No | Format for naming Docker images. |
| `APP_IMAGE_LABEL` | `latest` | No | The label used for Docker images. |
| `APP_IMAGE_BUILD_TIMEOUT_SEC` | `300` | No | Timeout in seconds for building Docker images. |
| `APP_SERVICE_SETUP_TIMEOUT_SEC` | `300` | No | Timeout in seconds for setting up Knative services. |
| `APP_MAX_ERROR_LOG_LINES` | `20` | No | Maximum number of error log lines to return in message. |
| `APP_MAX_ERROR_LOG_CHARS` | `1000` | No | Maximum number of error log characters to return in message. |
| `APP_TEMPLATE_IMAGE` | `${app.docker-registry}/builder-template:latest` | No | The Docker image used as the template for building. |
| `APP_BUILDER_IMAGE` | `gcr.io/kaniko-project/executor:latest` | No | The Docker image used for building applications. |
| `APP_TEMPLATE_CONTAINER` | `template` | No | Name of the template container in Kubernetes job. |
| `APP_BUILDER_CONTAINER` | `builder` | No | Name of the builder container in Kubernetes job. |
| `APP_SERVICE_CONTAINER` | `app-container` | No | Name of the service container. |
| `APP_DEFAULT_RUNTIME` | `python3.11` | No | Default runtime for Python applications. |
| `APP_DOCKER_REGISTRY_AUTH` | `NONE` | No | Authentication method for Docker registry (NONE, BASIC). |
| `APP_DOCKER_REGISTRY_USER` | | Conditional | Username for Docker registry when auth is BASIC. |
| `APP_DOCKER_REGISTRY_PASS` | | Conditional | Password for Docker registry when auth is BASIC. |

## Usage

Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:3.4.0'
implementation 'org.springframework.boot:spring-boot-starter-webflux:3.4.0'
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.2'

testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
Expand Down
132 changes: 66 additions & 66 deletions src/main/java/com/epam/aidial/config/AppConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,66 +1,66 @@
package com.epam.aidial.config;

import com.epam.aidial.kubernetes.knative.V1Service;
import io.kubernetes.client.openapi.models.V1Job;
import io.kubernetes.client.openapi.models.V1Secret;
import io.kubernetes.client.util.Yaml;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@ConfigurationProperties(prefix = "app")
public class AppConfiguration {
@Getter
private V1Secret secretConfig;
private String secretConfigString;

@Getter
private V1Job jobConfig;
private String jobConfigString;

@Getter
private V1Service serviceConfig;
private String serviceConfigString;

@Getter
@Setter
private Map<String, RuntimeConfiguration> runtimes;

public void setSecretConfig(V1Secret secretConfig) {
this.secretConfig = secretConfig;
this.secretConfigString = Yaml.dump(secretConfig);
}

public void setJobConfig(V1Job jobConfig) {
this.jobConfig = jobConfig;
this.jobConfigString = Yaml.dump(jobConfig);
}

public void setServiceConfig(V1Service serviceConfig) {
this.serviceConfig = serviceConfig;
this.serviceConfigString = Yaml.dump(serviceConfig);
}

public V1Secret cloneSecretConfig() {
return Yaml.loadAs(secretConfigString, V1Secret.class);
}

public V1Job cloneJobConfig() {
return Yaml.loadAs(jobConfigString, V1Job.class);
}

public V1Service cloneServiceConfig() {
return Yaml.loadAs(serviceConfigString, V1Service.class);
}

@Data
public static class RuntimeConfiguration {
private String image;
private String profile;
}
}
package com.epam.aidial.config;

import com.epam.aidial.kubernetes.knative.V1Service;
import io.kubernetes.client.openapi.models.V1Job;
import io.kubernetes.client.openapi.models.V1Secret;
import io.kubernetes.client.util.Yaml;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@ConfigurationProperties(prefix = "app")
public class AppConfiguration {
@Getter
private V1Secret secretConfig;
private String secretConfigString;

@Getter
private V1Job jobConfig;
private String jobConfigString;

@Getter
private V1Service serviceConfig;
private String serviceConfigString;

@Getter
@Setter
private Map<String, RuntimeConfiguration> runtimes;

public void setSecretConfig(V1Secret secretConfig) {
this.secretConfig = secretConfig;
this.secretConfigString = Yaml.dump(secretConfig);
}

public void setJobConfig(V1Job jobConfig) {
this.jobConfig = jobConfig;
this.jobConfigString = Yaml.dump(jobConfig);
}

public void setServiceConfig(V1Service serviceConfig) {
this.serviceConfig = serviceConfig;
this.serviceConfigString = Yaml.dump(serviceConfig);
}

public V1Secret cloneSecretConfig() {
return Yaml.loadAs(secretConfigString, V1Secret.class);
}

public V1Job cloneJobConfig() {
return Yaml.loadAs(jobConfigString, V1Job.class);
}

public V1Service cloneServiceConfig() {
return Yaml.loadAs(serviceConfigString, V1Service.class);
}

@Data
public static class RuntimeConfiguration {
private String image;
private String profile;
}
}
6 changes: 6 additions & 0 deletions src/main/java/com/epam/aidial/config/DockerAuthScheme.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.epam.aidial.config;

public enum DockerAuthScheme {
NONE,
BASIC
}
66 changes: 33 additions & 33 deletions src/main/java/com/epam/aidial/config/WebFluxConfig.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
package com.epam.aidial.config;

import com.epam.aidial.util.KubernetesUtils;
import io.kubernetes.client.openapi.ApiClient;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration
public class WebFluxConfig {
@Bean
public ApiClient buildKubeClient(
@Value("${app.kube-config}") String configPath,
@Value("${app.build-context:#{null}}") String context) throws IOException {
return KubernetesUtils.createClient(configPath, context);
}

@Bean
public ApiClient deployKubeClient(
@Value("${app.kube-config}") String configPath,
@Value("${app.deploy-context:#{null}}") String context) throws IOException {
return KubernetesUtils.createClient(configPath, context);
}

@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.build();
}
}
package com.epam.aidial.config;

import com.epam.aidial.util.KubernetesUtils;
import io.kubernetes.client.openapi.ApiClient;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration
public class WebFluxConfig {
@Bean
public ApiClient buildKubeClient(
@Value("${app.kube-config}") String configPath,
@Value("${app.build-context:#{null}}") String context) throws IOException {
return KubernetesUtils.createClient(configPath, context);
}

@Bean
public ApiClient deployKubeClient(
@Value("${app.kube-config}") String configPath,
@Value("${app.deploy-context:#{null}}") String context) throws IOException {
return KubernetesUtils.createClient(configPath, context);
}

@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.build();
}
}
Loading

0 comments on commit 6218876

Please sign in to comment.