Skip to content

Commit

Permalink
fix: Also build socat for ports (#55)
Browse files Browse the repository at this point in the history
* fix: Also build socat for ports

* Minor fixes

* Minor fixes
  • Loading branch information
gonzalezzfelipe authored Apr 25, 2024
1 parent 469f3cb commit 854613d
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 51 deletions.
21 changes: 14 additions & 7 deletions operator/src/backend-with-storage/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { V1StatefulSet, V1PersistentVolumeClaim, PatchUtils, V1Container, V1EnvV
import { getClients, readProjectUnsecure, Network, namespaceToSlug, DependencyResource, ServicePlugin } from '@demeter-sdk/framework';
import { API_VERSION, API_GROUP, PLURAL, SINGULAR, KIND } from './constants';
import { CustomResource, CustomResourceResponse, BackendWithStorage, StorageClass } from '@demeter-run/workloads-types';
import { buildEnvVars, cardanoNodeDep, getDependenciesForNetwork, isCardanoNodeEnabled } from '../shared/dependencies';
import { buildEnvVars, cardanoNodeDep, cardanoNodePort, getDependenciesForNetwork, isCardanoNodeEnabled } from '../shared/dependencies';
import {
getComputeDCUPerMin,
getNetworkFromAnnotations,
Expand All @@ -15,8 +15,9 @@ import {
workloadVolumes,
} from '../shared';
import { checkConfigMapExistsOrCreate, configmap } from '../shared/configmap';
import { buildSocatContainer } from '../shared/cardano-node-helper';
import { buildPortEnvVars } from '../shared/ports';
import { buildSocatContainer, buildSocatContainerForPort } from '../shared/cardano-node-helper';
import { buildPortEnvVars, getPortsForNetwork } from '../shared/ports';
import { ServiceInstanceWithStatusAndKind } from '../services';

const tolerations = [
{
Expand Down Expand Up @@ -56,12 +57,14 @@ export async function handleResource(

const network = getNetworkFromAnnotations(spec.annotations) as Network;
const deps = await getDependenciesForNetwork(project, network);
const portEnvVars = await buildPortEnvVars(project, network);
const ports = await getPortsForNetwork(project, network);
const portEnvVars = await buildPortEnvVars(ports);
const depsEnvVars = await buildEnvVars(deps, network);
const envVars = [...depsEnvVars, ...portEnvVars];
const cardanoNode = cardanoNodeDep(deps);
const cardanoNodePortInstance = cardanoNodePort(ports);
const volumesList = workloadVolumes(name, !!cardanoNode);
const containerList = containers(spec, envVars, cardanoNode);
const containerList = containers(spec, envVars, cardanoNode, cardanoNodePortInstance);
try {
await apps.readNamespacedStatefulSet(name, ns);
//@TODO sync
Expand Down Expand Up @@ -342,9 +345,11 @@ function containers(
spec: BackendWithStorage.Spec,
envVars: V1EnvVar[],
cardanoNodeDep: { dependency: DependencyResource; service: ServicePlugin } | null,
cardanoNodePort: ServiceInstanceWithStatusAndKind | null,
): V1Container[] {
const args = spec.args ? spec.args.split(' ') : [];
const command = spec.command ? spec.command.split(' ') : [];

const volumeMounts: V1VolumeMount[] = [
{
name: 'storage',
Expand All @@ -356,7 +361,7 @@ function containers(
},
];

if (!!cardanoNodeDep) {
if (!!cardanoNodePort || !!cardanoNodeDep) {
volumeMounts.push({
name: 'ipc',
mountPath: '/ipc',
Expand All @@ -376,7 +381,9 @@ function containers(
},
];

if (!!cardanoNodeDep) {
if (!!cardanoNodePort) {
containers.push(buildSocatContainerForPort(cardanoNodePort));
} else if (!!cardanoNodeDep) {
containers.push(buildSocatContainer(cardanoNodeDep.dependency, cardanoNodeDep.service));
}

Expand Down
21 changes: 14 additions & 7 deletions operator/src/backend/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { PatchUtils, V1Container, V1EnvVar, V1Volume, V1VolumeMount, V1Deploymen
import { getClients, readProjectUnsecure, Network, namespaceToSlug, DependencyResource, ServicePlugin } from '@demeter-sdk/framework';
import { API_VERSION, API_GROUP, PLURAL } from './constants';
import { CustomResource, CustomResourceResponse, Backend, Pod, WorkloadStatus } from '@demeter-run/workloads-types';
import { buildEnvVars, cardanoNodeDep, getDependenciesForNetwork, isCardanoNodeEnabled } from '../shared/dependencies';
import { buildEnvVars, cardanoNodeDep, cardanoNodePort, getDependenciesForNetwork } from '../shared/dependencies';
import { getComputeDCUPerMin, getDeploymentStatus, getNetworkFromAnnotations, getResourcesFromComputeClass, workloadVolumes } from '../shared';
import { checkConfigMapExistsOrCreate, configmap } from '../shared/configmap';
import { buildSocatContainer } from '../shared/cardano-node-helper';
import { buildPortEnvVars } from '../shared/ports';
import { buildSocatContainer, buildSocatContainerForPort } from '../shared/cardano-node-helper';
import { buildPortEnvVars, getPortsForNetwork } from '../shared/ports';
import { ServiceInstanceWithStatusAndKind } from '../services';

const tolerations = [
{
Expand Down Expand Up @@ -45,12 +46,14 @@ export async function handleResource(

const network = getNetworkFromAnnotations(spec.annotations) as Network;
const deps = await getDependenciesForNetwork(project, network);
const portEnvVars = await buildPortEnvVars(project, network);
const ports = await getPortsForNetwork(project, network);
const portEnvVars = await buildPortEnvVars(ports);
const depsEnvVars = await buildEnvVars(deps, network);
const envVars = [...depsEnvVars, ...portEnvVars];
const cardanoNode = cardanoNodeDep(deps);
const cardanoNodePortInstance = cardanoNodePort(ports);
const volumesList = workloadVolumes(name, !!cardanoNode);
const containerList = containers(spec, envVars, cardanoNode);
const containerList = containers(spec, envVars, cardanoNode, cardanoNodePortInstance);
try {
await apps.readNamespacedDeployment(name, ns);
await checkConfigMapExistsOrCreate(core, ns, name, spec, owner);
Expand Down Expand Up @@ -226,17 +229,19 @@ function containers(
spec: Backend.Spec,
envVars: V1EnvVar[],
cardanoNodeDep: { dependency: DependencyResource; service: ServicePlugin } | null,
cardanoNodePort: ServiceInstanceWithStatusAndKind | null,
): V1Container[] {
const args = spec.args ? spec.args.split(' ') : [];
const command = spec.command ? spec.command.split(' ') : [];

const volumeMounts: V1VolumeMount[] = [
{
name: 'config',
mountPath: '/etc/config',
},
];

if (!!cardanoNodeDep) {
if (!!cardanoNodePort || !!cardanoNodeDep) {
volumeMounts.push({
name: 'ipc',
mountPath: '/ipc',
Expand All @@ -256,7 +261,9 @@ function containers(
},
];

if (!!cardanoNodeDep) {
if (!!cardanoNodePort) {
containers.push(buildSocatContainerForPort(cardanoNodePort));
} else if (!!cardanoNodeDep) {
containers.push(buildSocatContainer(cardanoNodeDep.dependency, cardanoNodeDep.service));
}

Expand Down
21 changes: 14 additions & 7 deletions operator/src/frontend/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { PatchUtils, V1Container, V1EnvVar, V1Volume, V1VolumeMount, V1Deploymen
import { getClients, readProjectUnsecure, Network, namespaceToSlug, DependencyResource, ServicePlugin } from '@demeter-sdk/framework';
import { API_VERSION, API_GROUP, PLURAL } from './constants';
import { CustomResource, CustomResourceResponse, Frontend, WorkloadStatus } from '@demeter-run/workloads-types';
import { buildEnvVars, cardanoNodeDep, getDependenciesForNetwork } from '../shared/dependencies';
import { buildEnvVars, cardanoNodeDep, cardanoNodePort, getDependenciesForNetwork } from '../shared/dependencies';
import { getComputeDCUPerMin, getDeploymentStatus, getNetworkFromAnnotations, getResourcesFromComputeClass, workloadVolumes } from '../shared';
import { checkConfigMapExistsOrCreate, configmap } from '../shared/configmap';
import { buildSocatContainer } from '../shared/cardano-node-helper';
import { buildPortEnvVars } from '../shared/ports';
import { buildSocatContainer, buildSocatContainerForPort } from '../shared/cardano-node-helper';
import { buildPortEnvVars, getPortsForNetwork } from '../shared/ports';
import { ServiceInstanceWithStatusAndKind } from '../services';

const tolerations = [
{
Expand Down Expand Up @@ -45,12 +46,14 @@ export async function handleResource(

const network = getNetworkFromAnnotations(spec.annotations) as Network;
const deps = await getDependenciesForNetwork(project, network);
const portEnvVars = await buildPortEnvVars(project, network);
const ports = await getPortsForNetwork(project, network);
const portEnvVars = await buildPortEnvVars(ports);
const depsEnvVars = await buildEnvVars(deps, network);
const envVars = [...depsEnvVars, ...portEnvVars];
const cardanoNode = cardanoNodeDep(deps);
const cardanoNodePortInstance = cardanoNodePort(ports);
const volumesList = workloadVolumes(name, !!cardanoNode);
const containerList = containers(spec, envVars, cardanoNode);
const containerList = containers(spec, envVars, cardanoNode, cardanoNodePortInstance);
try {
await apps.readNamespacedDeployment(name, ns);
await checkConfigMapExistsOrCreate(core, ns, name, spec, owner);
Expand Down Expand Up @@ -211,17 +214,19 @@ function containers(
spec: Frontend.Spec,
envVars: V1EnvVar[],
cardanoNodeDep: { dependency: DependencyResource; service: ServicePlugin } | null,
cardanoNodePort: ServiceInstanceWithStatusAndKind | null,
): V1Container[] {
const args = spec.args ? spec.args.split(' ') : [];
const command = spec.command ? spec.command.split(' ') : [];

const volumeMounts: V1VolumeMount[] = [
{
name: 'config',
mountPath: '/etc/config',
},
];

if (!!cardanoNodeDep) {
if (!!cardanoNodePort || !!cardanoNodeDep) {
volumeMounts.push({
name: 'ipc',
mountPath: '/ipc',
Expand All @@ -241,7 +246,9 @@ function containers(
},
];

if (!!cardanoNodeDep) {
if (!!cardanoNodePort) {
containers.push(buildSocatContainerForPort(cardanoNodePort));
} else if (!!cardanoNodeDep) {
containers.push(buildSocatContainer(cardanoNodeDep.dependency, cardanoNodeDep.service));
}

Expand Down
6 changes: 5 additions & 1 deletion operator/src/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const nodesServiceV2 = nodesV2.SERVICE_PLUGIN;


export type ServiceInstanceWithStatus = ServiceInstance & { status: any; spec: any };
export type ServiceInstanceWithStatusAndKind = ServiceInstanceWithStatus & { kind: string };

/**
* Returns all the registered services metadata
Expand All @@ -30,7 +31,10 @@ export async function getAllServices(): Promise<ServiceMetadata[]> {

// checks the service feature flag is enabled
for (const id of serviceIds) {
res.push(getServiceMetadata(id));
const metadata = getServiceMetadata(id);
if (metadata) {
res.push(metadata);
}
}

return res;
Expand Down
24 changes: 23 additions & 1 deletion operator/src/shared/cardano-node-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { DependencyResource, EnvVar, Network, ServicePlugin, ServicePort } from
import { V1Container } from '@kubernetes/client-node';
import { ServiceInstanceWithStatus } from '../services';

const CARDANO_NODE_PORT_PORT = 9443;
const MAGIC_BY_NETWORK: Record<string, string> = {
preview: '2',
preprod: '1',
Expand Down Expand Up @@ -57,7 +58,7 @@ export function getCardanoNodeEnvVars(dep: DependencyResource, service: ServiceP
export function getCardanoNodePortEnvVars(instance: ServiceInstanceWithStatus): EnvVar[] {
const network = instance.spec.network;
const host = instance.status?.authenticatedEndpointUrl || 'provisioning...';
const port = 9443;
const port = CARDANO_NODE_PORT_PORT;
return [
{ name: 'CARDANO_NODE_HOST', value: host },
{ name: 'CARDANO_NODE_PORT', value: port },
Expand Down Expand Up @@ -85,3 +86,24 @@ export function buildSocatContainer(dep: DependencyResource, service: ServicePlu
],
};
}

export function buildSocatContainerForPort(instance: ServiceInstanceWithStatus): V1Container {
return {
name: 'socat',
image: 'alpine/socat',
securityContext: {
runAsUser: 1000,
runAsGroup: 1000,
},
args: [
'UNIX-LISTEN:/ipc/node.socket,reuseaddr,fork,unlink-early',
`OPENSSL:${instance.status?.authenticatedEndpointUrl}:${CARDANO_NODE_PORT_PORT}`
],
volumeMounts: [
{
name: 'ipc',
mountPath: '/ipc',
},
],
};
}
15 changes: 14 additions & 1 deletion operator/src/shared/dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DependencyResource, listDependencies, loadDependencyConnections, Network, ProjectSpec, ServicePlugin } from '@demeter-sdk/framework';
import { V1EnvVar } from '@kubernetes/client-node';
import { getService } from '../services';
import { getService, ServiceInstanceWithStatusAndKind } from '../services';
import { getNetworkFromAnnotations } from '.';
import { getCardanoNodeEnvVars } from './cardano-node-helper';

Expand All @@ -21,6 +21,19 @@ export function isCardanoNodeEnabled(deps: DependencyResource[]): boolean {
return false;
}

export function cardanoNodePort(instances: ServiceInstanceWithStatusAndKind[]): ServiceInstanceWithStatusAndKind | null{
for (const instance of instances) {
if (instance.kind === 'CardanoNodePort') {
return instance;
}
}
return null;
}

export function isCardanoNodePortEnabled(instances: ServiceInstanceWithStatusAndKind[]): boolean {
return !!cardanoNodePort(instances);
}

export function cardanoNodeDep(deps: DependencyResource[]): { dependency: DependencyResource; service: ServicePlugin } | null {
for (const dep of deps) {
const service = getService(dep.spec.serviceId);
Expand Down
47 changes: 28 additions & 19 deletions operator/src/shared/ports.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
import { EnvVar, ProjectSpec } from '@demeter-sdk/framework';
import type { Network, ServiceMetadata } from '@demeter-sdk/framework';
import { getService, ServiceInstanceWithStatus, getAllServices } from '../services';
import { getService, ServiceInstanceWithStatus, ServiceInstanceWithStatusAndKind, getAllServices } from '../services';
import { getCardanoNodePortEnvVars } from './cardano-node-helper';


function removeSchema(url: string): string {
return url.replace("https://", '').replace("http://", '')
}

export function parseInstanceToEnvVars(instance: ServiceInstanceWithStatus, kind: string): EnvVar[] {
switch (kind) {
export async function getPortsForNetwork(project: ProjectSpec, network: Network): Promise<ServiceInstanceWithStatusAndKind[]> {
const output: ServiceInstanceWithStatusAndKind[] = [];
const services = (await getAllServices()).filter(service => service.key.includes('port'));

const projectInstances: { metadata: ServiceMetadata; instances: Promise<ServiceInstanceWithStatus[]> }[] = services.map(svc => {
const service = getService(svc.key)!;
return { metadata: service.metadata, instances: service.listProjectInstances(project) as Promise<ServiceInstanceWithStatus[]> };
});

for (const projectInstance of projectInstances) {
const inst = await projectInstance.instances;
inst.forEach(instance => {
if (instance.spec.network === network) {
output.push({ ...instance, kind: projectInstance.metadata.kind })
}
})
output.push()
}
return output;
}

export function parseInstanceToEnvVars(instance: ServiceInstanceWithStatusAndKind): EnvVar[] {
switch (instance.kind) {
case 'CardanoNodePort':
return getCardanoNodePortEnvVars(instance)
case 'MarlowePort':
Expand All @@ -27,23 +48,11 @@ export function parseInstanceToEnvVars(instance: ServiceInstanceWithStatus, kind
}
}

export async function buildPortEnvVars(project: ProjectSpec, network: Network): Promise<EnvVar[]> {
export async function buildPortEnvVars(instances: ServiceInstanceWithStatusAndKind[]): Promise<EnvVar[]> {
const output: EnvVar[] = [];
const services = (await getAllServices()).filter(service => service.key.includes('port'));

const projectInstances: { metadata: ServiceMetadata; instances: Promise<ServiceInstanceWithStatus[]> }[] = services.map(svc => {
const service = getService(svc.key)!;
return { metadata: service.metadata, instances: service.listProjectInstances(project) as Promise<ServiceInstanceWithStatus[]> };
instances.forEach(item => {
const envVars = parseInstanceToEnvVars(item);
output.push(...envVars);
});

for (const projectInstance of projectInstances) {
const inst = await projectInstance.instances;
inst.forEach(item => {
if (item.spec.network === network) {
const envVars = parseInstanceToEnvVars(item, projectInstance.metadata.kind);
output.push(...envVars);
}
});
}
return output
}
Loading

0 comments on commit 854613d

Please sign in to comment.