215 lines
5.7 KiB
Go
215 lines
5.7 KiB
Go
package application
|
|
|
|
import (
|
|
v1 "antoine-roux.tk/projects/go/pulumi-library/crds/kubernetes/certmanager/v1"
|
|
"antoine-roux.tk/projects/go/pulumi-library/pkg/exposition"
|
|
"antoine-roux.tk/projects/go/pulumi-library/pkg/meta"
|
|
"antoine-roux.tk/projects/go/pulumi-library/pkg/workload"
|
|
"errors"
|
|
"fmt"
|
|
appsv1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/apps/v1"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
|
"slices"
|
|
)
|
|
|
|
type Configuration struct {
|
|
Name string
|
|
Namespace string
|
|
Images []ImagesConfiguration
|
|
Dns *string
|
|
Replicas *int
|
|
Env map[string]string
|
|
AllowAllOrigin bool
|
|
}
|
|
|
|
type ImagesConfiguration struct {
|
|
Image string
|
|
Path string
|
|
Health string
|
|
}
|
|
|
|
type CreatedApplication struct {
|
|
ApplicationName pulumi.StringOutput `pulumi:"application"`
|
|
DeploymentName []pulumi.StringOutput `pulumi:"deployment"`
|
|
}
|
|
|
|
type application struct {
|
|
pulumi.ResourceState
|
|
|
|
Name string
|
|
Namespace string
|
|
Services []service
|
|
Dns string
|
|
Replicas int
|
|
Env map[string]string
|
|
AllowAllOrigin bool
|
|
|
|
shouldCreateDns bool
|
|
shouldCreateCertificate bool
|
|
shouldCreateIngress bool
|
|
}
|
|
|
|
type service struct {
|
|
Image string
|
|
Path string
|
|
Health string
|
|
}
|
|
|
|
func NewApplication(ctx *pulumi.Context, configuration *Configuration) (*CreatedApplication, error) {
|
|
|
|
if configuration.Name != "" && len(configuration.Images) > 0 {
|
|
|
|
application := &application{
|
|
Name: configuration.Name,
|
|
Namespace: configuration.Namespace,
|
|
Env: configuration.Env,
|
|
AllowAllOrigin: configuration.AllowAllOrigin,
|
|
}
|
|
|
|
var preventDuplicatePath []string
|
|
for _, image := range configuration.Images {
|
|
serviceConfiguration := service{
|
|
Image: image.Image,
|
|
Path: image.Path,
|
|
Health: image.Health,
|
|
}
|
|
if image.Path == "" {
|
|
serviceConfiguration.Path = "/"
|
|
}
|
|
if image.Health == "" {
|
|
serviceConfiguration.Health = "/"
|
|
}
|
|
if slices.Contains(preventDuplicatePath, serviceConfiguration.Path) {
|
|
return nil, errors.New("duplicate path in ingress applicationConfiguration")
|
|
}
|
|
application.Services = append(application.Services, serviceConfiguration)
|
|
preventDuplicatePath = append(preventDuplicatePath, serviceConfiguration.Path)
|
|
}
|
|
|
|
if configuration.Replicas != nil {
|
|
application.Replicas = *configuration.Replicas
|
|
} else {
|
|
application.Replicas = 1
|
|
}
|
|
|
|
if configuration.Dns != nil {
|
|
application.Dns = *configuration.Dns
|
|
application.shouldCreateDns = true
|
|
application.shouldCreateCertificate = true
|
|
application.shouldCreateIngress = true
|
|
}
|
|
|
|
err := ctx.RegisterComponentResource("pkg:application:CreatedApplication", configuration.Name, application)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return application.createResources(ctx)
|
|
} else {
|
|
return nil, errors.New("missing required value ApplicationName or Image during generic application construction")
|
|
}
|
|
}
|
|
|
|
func (application *application) createResources(ctx *pulumi.Context) (*CreatedApplication, error) {
|
|
createdApplication := &CreatedApplication{
|
|
ApplicationName: pulumi.String(application.Name).ToStringOutput(),
|
|
}
|
|
|
|
namespaceConfiguration := &meta.NamespaceConfiguration{
|
|
Name: application.Name,
|
|
Namespace: application.Namespace,
|
|
}
|
|
namespace, err := namespaceConfiguration.CreateNamespace(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var deployments []*appsv1.Deployment
|
|
var ingressServices []exposition.IngressServices
|
|
|
|
for index, service := range application.Services {
|
|
indexedName := fmt.Sprintf("%s-%d", application.Name, index)
|
|
appLabels := pulumi.StringMap{
|
|
"app.kubernetes.io/name": pulumi.String(indexedName),
|
|
}
|
|
|
|
deploymentConfiguration := &workload.DeploymentConfiguration{
|
|
Name: indexedName,
|
|
Env: application.Env,
|
|
Replicas: application.Replicas,
|
|
ImageReference: &workload.ImageReference{
|
|
Image: service.Image,
|
|
Health: service.Health,
|
|
},
|
|
}
|
|
deployment, err := deploymentConfiguration.CreateDeployment(ctx, namespace, application, appLabels)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
createdApplication.DeploymentName = append(createdApplication.DeploymentName, deployment.Metadata.Name().Elem())
|
|
|
|
serviceConfiguration := exposition.ServiceConfiguration{
|
|
Name: indexedName,
|
|
}
|
|
createdService, err := serviceConfiguration.CreateService(ctx, namespace, application, appLabels)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ingressServices = append(ingressServices,
|
|
exposition.IngressServices{
|
|
Service: createdService,
|
|
Path: service.Path,
|
|
})
|
|
deployments = append(deployments, deployment)
|
|
}
|
|
|
|
if application.shouldCreateDns {
|
|
dnsConfiguration := &exposition.DnsConfiguration{
|
|
Name: application.Name,
|
|
Dns: application.Dns,
|
|
}
|
|
_, err = dnsConfiguration.CreateDNSRecord(ctx, namespace, application)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
}
|
|
var certificate *v1.Certificate
|
|
if application.shouldCreateCertificate {
|
|
certificateConfiguration := &meta.CertificateConfiguration{
|
|
Name: application.Name,
|
|
Dns: application.Dns,
|
|
}
|
|
certificate, err = certificateConfiguration.CreateCertificate(ctx, namespace, application)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
if application.shouldCreateIngress {
|
|
ingressConfiguration := exposition.NewIngressConfiguration(
|
|
application.Name,
|
|
application.Dns,
|
|
application.AllowAllOrigin,
|
|
ingressServices,
|
|
)
|
|
|
|
err = ingressConfiguration.CreateIngress(ctx, namespace, application, certificate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
outs := pulumi.Map{}
|
|
for i, deployment := range deployments {
|
|
outs[fmt.Sprintf("deployment-%d", i)] = deployment.Metadata.Name()
|
|
}
|
|
|
|
err = ctx.RegisterResourceOutputs(application, outs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return createdApplication, nil
|
|
}
|