opinions

package
v0.0.0-...-7f751fe Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 18, 2022 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var SpringBoot = Opinions{
	&BasicOpinion{
		Id: "spring-boot",
		ApplicableFunc: func(applied AppliedOpinions, imageMetadata cnb.BuildMetadata) bool {
			bootMetadata := NewSpringBootBOMMetadata(imageMetadata)
			return bootMetadata.HasDependency("spring-boot")
		},
		ApplyFunc: func(ctx context.Context, target Resource, containerIdx int, imageMetadata cnb.BuildMetadata) error {
			bootMetadata := NewSpringBootBOMMetadata(imageMetadata)
			setLabel(target, "apps.mononoke.local/framework", "spring-boot")
			for _, d := range bootMetadata.Dependencies {
				if d.Name == "spring-boot" {
					setAnnotation(target, "boot.spring.io/version", d.Version)
					break
				}
			}
			return nil
		},
	},
	&BasicOpinion{
		Id: "spring-boot-graceful-shutdown",
		ApplicableFunc: func(applied AppliedOpinions, imageMetadata cnb.BuildMetadata) bool {
			bootMetadata := NewSpringBootBOMMetadata(imageMetadata)
			return bootMetadata.HasDependencyConstraint("spring-boot", ">= 2.3.0-0") && bootMetadata.HasDependency(
				"spring-boot-starter-tomcat",
				"spring-boot-starter-jetty",
				"spring-boot-starter-reactor-netty",
				"spring-boot-starter-undertow",
			)
		},
		ApplyFunc: func(ctx context.Context, target Resource, containerIdx int, imageMetadata cnb.BuildMetadata) error {
			applicationProperties := GetSpringApplicationProperties(ctx)
			if _, ok := applicationProperties["server.shutdown.grace-period"]; ok {

				return nil
			}
			var k8sGracePeriodSeconds int64 = 30 // default k8s grace period is 30 seconds
			if target.PodTemplate().Spec.TerminationGracePeriodSeconds != nil {
				k8sGracePeriodSeconds = *target.PodTemplate().Spec.TerminationGracePeriodSeconds
			}
			target.PodTemplate().Spec.TerminationGracePeriodSeconds = &k8sGracePeriodSeconds

			bootGracePeriodSeconds := int(math.Floor(0.8 * float64(k8sGracePeriodSeconds)))
			applicationProperties["server.shutdown.grace-period"] = fmt.Sprintf("%ds", bootGracePeriodSeconds)
			return nil
		},
	},
	&BasicOpinion{
		Id: "spring-web-port",
		ApplicableFunc: func(applied AppliedOpinions, imageMetadata cnb.BuildMetadata) bool {
			bootMetadata := NewSpringBootBOMMetadata(imageMetadata)
			return bootMetadata.HasDependency("spring-web")
		},
		ApplyFunc: func(ctx context.Context, target Resource, containerIdx int, imageMetadata cnb.BuildMetadata) error {
			applicationProperties := GetSpringApplicationProperties(ctx)

			serverPort := applicationProperties.Default("server.port", "8080")
			port, err := strconv.Atoi(serverPort)
			if err != nil {
				return err
			}

			c := &target.PodTemplate().Spec.Containers[containerIdx]

			if name, cp := findContainerPort(target.PodTemplate().Spec, int32(port)); cp == nil {
				c.Ports = append(c.Ports, corev1.ContainerPort{
					ContainerPort: int32(port),
					Protocol:      corev1.ProtocolTCP,
				})
			} else if name != c.Name {

				return fmt.Errorf("desired port %s is in use by container %q, set 'server.port' boot property to an open port", serverPort, name)
			}

			return nil
		},
	},
	&BasicOpinion{
		Id: "spring-boot-actuator",
		ApplicableFunc: func(applied AppliedOpinions, imageMetadata cnb.BuildMetadata) bool {
			bootMetadata := NewSpringBootBOMMetadata(imageMetadata)
			return bootMetadata.HasDependency("spring-boot-actuator")
		},
		ApplyFunc: func(ctx context.Context, target Resource, containerIdx int, imageMetadata cnb.BuildMetadata) error {
			applicationProperties := GetSpringApplicationProperties(ctx)

			managementPort := applicationProperties.Default("management.server.port", applicationProperties["server.port"])
			managementBasePath := applicationProperties.Default("management.endpoints.web.base-path", "/actuator")
			managementScheme := corev1.URISchemeHTTP
			if applicationProperties["management.server.ssl.enabled"] == "true" {
				managementScheme = corev1.URISchemeHTTPS
			}

			setAnnotation(target, "boot.spring.io/actuator", fmt.Sprintf("%s://:%s%s", strings.ToLower(string(managementScheme)), managementPort, managementBasePath))

			return nil
		},
	},
	&BasicOpinion{
		Id: "spring-boot-actuator-probes",
		ApplicableFunc: func(applied AppliedOpinions, imageMetadata cnb.BuildMetadata) bool {
			bootMetadata := NewSpringBootBOMMetadata(imageMetadata)
			return bootMetadata.HasDependency("spring-boot-actuator")
		},
		ApplyFunc: func(ctx context.Context, target Resource, containerIdx int, imageMetadata cnb.BuildMetadata) error {
			bootMetadata := NewSpringBootBOMMetadata(imageMetadata)
			applicationProperties := GetSpringApplicationProperties(ctx)

			if v := applicationProperties.Default("management.health.probes.enabled", "true"); v != "true" {

				return nil
			}

			managementBasePath := applicationProperties["management.endpoints.web.base-path"]
			managementPort, err := strconv.Atoi(applicationProperties["management.server.port"])
			if err != nil {
				return err
			}
			managementScheme := corev1.URISchemeHTTP
			if applicationProperties["management.server.ssl.enabled"] == "true" {
				managementScheme = corev1.URISchemeHTTPS
			}

			var livenessEndpoint, readinessEndpoint string
			if bootMetadata.HasDependencyConstraint("spring-boot-actuator", ">= 2.3.0-0") {
				livenessEndpoint = "/health/liveness"
				readinessEndpoint = "/health/readiness"
			} else {
				livenessEndpoint = "/info"
				readinessEndpoint = "/info"
			}

			c := &target.PodTemplate().Spec.Containers[containerIdx]

			if c.StartupProbe == nil {

			}
			if c.LivenessProbe == nil {
				c.LivenessProbe = &corev1.Probe{

					InitialDelaySeconds: 30,
				}
			}
			if c.LivenessProbe.Handler == (corev1.Handler{}) {
				c.LivenessProbe.Handler = corev1.Handler{
					HTTPGet: &corev1.HTTPGetAction{
						Path:   managementBasePath + livenessEndpoint,
						Port:   intstr.FromInt(managementPort),
						Scheme: managementScheme,
					},
				}
			}
			if c.ReadinessProbe == nil {
				c.ReadinessProbe = &corev1.Probe{}
			}
			if c.ReadinessProbe.Handler == (corev1.Handler{}) {
				c.ReadinessProbe.Handler = corev1.Handler{
					HTTPGet: &corev1.HTTPGetAction{
						Path:   managementBasePath + readinessEndpoint,
						Port:   intstr.FromInt(managementPort),
						Scheme: managementScheme,
					},
				}
			}

			return nil
		},
	},

	&SpringBootServiceIntent{
		Id:        "service-intent-mysql",
		LabelName: "services.mononoke.local/mysql",
		Dependencies: sets.NewString(
			"mysql-connector-java",
			"r2dbc-mysql",
		),
	},
	&SpringBootServiceIntent{
		Id:        "service-intent-postgres",
		LabelName: "services.mononoke.local/postgres",
		Dependencies: sets.NewString(
			"postgresql",
			"r2dbc-postgresql",
		),
	},
	&SpringBootServiceIntent{
		Id:        "service-intent-mongodb",
		LabelName: "services.mononoke.local/mongodb",
		Dependencies: sets.NewString(
			"mongodb-driver-core",
		),
	},
	&SpringBootServiceIntent{
		Id:        "service-intent-rabbitmq",
		LabelName: "services.mononoke.local/rabbitmq",
		Dependencies: sets.NewString(
			"amqp-client",
		),
	},
	&SpringBootServiceIntent{
		Id:        "service-intent-redis",
		LabelName: "services.mononoke.local/redis",
		Dependencies: sets.NewString(
			"jedis",
		),
	},
	&SpringBootServiceIntent{
		Id:        "service-intent-kafka",
		LabelName: "services.mononoke.local/kafka",
		Dependencies: sets.NewString(
			"kafka-clients",
		),
	},
	&SpringBootServiceIntent{
		Id:        "service-intent-kafka-streams",
		LabelName: "services.mononoke.local/kafka-streams",
		Dependencies: sets.NewString(
			"kafka-streams",
		),
	},
}

Functions

func StashSpringApplicationProperties

func StashSpringApplicationProperties(ctx context.Context, props SpringApplicationProperties) context.Context

Types

type AppliedOpinions

type AppliedOpinions []string

func (AppliedOpinions) Has

func (os AppliedOpinions) Has(id string) bool

type BasicOpinion

type BasicOpinion struct {
	Id             string
	ApplicableFunc func(applied AppliedOpinions, metadata cnb.BuildMetadata) bool
	ApplyFunc      func(ctx context.Context, target Resource, containerIdx int, metadata cnb.BuildMetadata) error
}

func (*BasicOpinion) Applicable

func (o *BasicOpinion) Applicable(applied AppliedOpinions, metadata cnb.BuildMetadata) bool

func (*BasicOpinion) Apply

func (o *BasicOpinion) Apply(ctx context.Context, target Resource, containerIdx int, metadata cnb.BuildMetadata) error

func (*BasicOpinion) GetId

func (o *BasicOpinion) GetId() string

type Opinion

type Opinion interface {
	GetId() string
	Applicable(applied AppliedOpinions, imageMetadata cnb.BuildMetadata) bool
	Apply(ctx context.Context, target Resource, containerIdx int, metadata cnb.BuildMetadata) error
}

type Opinions

type Opinions []Opinion

func (Opinions) Apply

func (os Opinions) Apply(ctx context.Context, target Resource, containerIdx int, imageMetadata cnb.BuildMetadata) ([]string, error)

type Resource

type Resource interface {
	metav1.ObjectMetaAccessor
	PodTemplate() *corev1.PodTemplateSpec
}

type SpringApplicationProperties

type SpringApplicationProperties map[string]string

func GetSpringApplicationProperties

func GetSpringApplicationProperties(ctx context.Context) SpringApplicationProperties

func (SpringApplicationProperties) Default

func (props SpringApplicationProperties) Default(key, value string) string

type SpringBootBOMMetadata

type SpringBootBOMMetadata struct {
	Classes      string                            `json:"classes"`
	ClassPath    []string                          `json:"classpath"`
	Dependencies []SpringBootBOMMetadataDependency `json:"dependencies"`
}

func NewSpringBootBOMMetadata

func NewSpringBootBOMMetadata(imageMetadata cnb.BuildMetadata) SpringBootBOMMetadata

func (*SpringBootBOMMetadata) Dependency

func (*SpringBootBOMMetadata) HasDependency

func (m *SpringBootBOMMetadata) HasDependency(names ...string) bool

func (*SpringBootBOMMetadata) HasDependencyConstraint

func (m *SpringBootBOMMetadata) HasDependencyConstraint(name, constraint string) bool

type SpringBootBOMMetadataDependency

type SpringBootBOMMetadataDependency struct {
	Name    string `json:"name"`
	Sha256  string `json:"sha256"`
	Version string `json:"version"`
}

type SpringBootServiceIntent

type SpringBootServiceIntent struct {
	Id           string
	LabelName    string
	Dependencies sets.String
}

func (*SpringBootServiceIntent) Applicable

func (o *SpringBootServiceIntent) Applicable(applied AppliedOpinions, metadata cnb.BuildMetadata) bool

func (*SpringBootServiceIntent) Apply

func (o *SpringBootServiceIntent) Apply(ctx context.Context, target Resource, containerIdx int, metadata cnb.BuildMetadata) error

func (*SpringBootServiceIntent) GetId

func (o *SpringBootServiceIntent) GetId() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL