halkyon.io/api@v1.0.0-rc.6/component/v1beta1/types.go (about)

     1  package v1beta1
     2  
     3  import (
     4  	"fmt"
     5  	"halkyon.io/api/capability/v1beta1"
     6  	common "halkyon.io/api/v1beta1"
     7  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     8  	"k8s.io/apimachinery/pkg/runtime/schema"
     9  	"strings"
    10  )
    11  
    12  const Kind string = "Component"
    13  
    14  type DeploymentMode string
    15  
    16  func (dm DeploymentMode) String() string {
    17  	return string(dm)
    18  }
    19  
    20  func (dm DeploymentMode) Equals(other DeploymentMode) bool {
    21  	return strings.ToLower(dm.String()) == strings.ToLower(other.String())
    22  }
    23  
    24  const (
    25  	DevDeploymentMode   DeploymentMode = "dev"
    26  	BuildDeploymentMode DeploymentMode = "build"
    27  )
    28  
    29  type BuildConfig struct {
    30  	// Type is the mode that we would like to use to perform a container image build.
    31  	// Optional. By default it is equal to s2i.
    32  	Type string `json:"type,omitempty"`
    33  	// URL is the Http or Web address of the Git repo to be cloned from the platforms such as : github, bitbucket, gitlab, ...
    34  	// The syntax of the URL is : HTTPS://<git_server>/<git_org>/project.git
    35  	URL string `json:"url"`
    36  	// Ref is the git reference of the repo.
    37  	// Optional. By default it is equal to "master".
    38  	Ref string `json:"ref"`
    39  	// moduleDirName is the name of the maven module / directory where build should be done.
    40  	// Optional. By default, it is equal to "."
    41  	ModuleDirName string `json:"moduleDirName,omitempty"`
    42  	// contextPath is the directory relative to the git repository where the s2i build must take place.
    43  	// Optional. By default, it is equal to "."
    44  	ContextPath string `json:"contextPath,omitempty"`
    45  	// Container image to be used as Base or From to build the final image
    46  	BaseImage string `json:"baseImage,omitempty"`
    47  }
    48  
    49  // ComponentSpec defines the desired state of Component
    50  // +k8s:openapi-gen=true
    51  type ComponentSpec struct {
    52  	// DeploymentMode indicates the strategy to be adopted to install the resources into a namespace
    53  	// and next to create a pod. 2 strategies are currently supported; inner and outer loop
    54  	// where outer loop refers to a build of the code and the packaging of the application into a container's image
    55  	// while the inner loop will install a pod's running a supervisord daemon used to trigger actions such as : assemble, run, ...
    56  	DeploymentMode DeploymentMode `json:"deploymentMode,omitempty"`
    57  	// Runtime is the framework/language used to start with a linux's container an application.
    58  	// It corresponds to one of the following values: spring-boot, vertx, thorntail, nodejs, python, php, ruby
    59  	// It will be used to select the appropriate runtime image and logic
    60  	Runtime string `json:"runtime,omitempty"`
    61  	// Runtime's version
    62  	Version string `json:"version,omitempty"`
    63  	// To indicate if we want to expose the service out side of the cluster as a route
    64  	ExposeService bool `json:"exposeService,omitempty"`
    65  	// Port is the HTTP/TCP port number used within the pod by the runtime
    66  	Port int32 `json:"port,omitempty"`
    67  	// Storage allows to specify the capacity and mode of the volume to be mounted for the pod
    68  	Storage Storage `json:"storage,omitempty"`
    69  	// Array of env variables containing extra/additional info to be used to configure the runtime
    70  	Envs     []common.NameValuePair `json:"envs,omitempty"`
    71  	Revision string                 `json:"revision,omitempty"`
    72  	// Build configuration used to execute a TekTon Build task
    73  	BuildConfig  BuildConfig        `json:"buildConfig,omitempty"`
    74  	Capabilities CapabilitiesConfig `json:"capabilities,omitempty"`
    75  }
    76  
    77  const (
    78  	// CapabilityParameterNamePrefix is a string prefixed to all capability parameters needed to pass information to capability
    79  	// implementations
    80  	CapabilityParameterNamePrefix = "halkyon."
    81  	// TargetComponentDefaultParameterName is the parameter name of the parameter recording which component is requesting the
    82  	// capability
    83  	TargetComponentDefaultParameterName = CapabilityParameterNamePrefix + "target.component"
    84  	// TargetDeploymentDefaultParameterName is the parameter name of the parameter recording the name of the deployment
    85  	// associated to the component requesting the capability
    86  	TargetDeploymentDefaultParameterName = CapabilityParameterNamePrefix + "target.deployment"
    87  	// TargetPortDefaultParameterName is the parameter name of the parameter recording the port of the service associated to
    88  	// the component requesting the capability
    89  	TargetPortDefaultParameterName = CapabilityParameterNamePrefix + "target.port"
    90  )
    91  
    92  // AddDefaultCapabilityParameters adds default parameters to the specified capability based on the information provided by the
    93  // specified component, returning whether the capability was updated as a result. Default parameter names use constants ending
    94  // with `DefaultParameterName`.
    95  func AddDefaultCapabilityParameters(toCapability *v1beta1.Capability, fromComponent *Component) (updated bool) {
    96  	updated = AddCapabilityParameterIfNeeded(common.NameValuePair{Name: TargetComponentDefaultParameterName, Value: fromComponent.GetName()}, toCapability) || updated
    97  	updated = AddCapabilityParameterIfNeeded(common.NameValuePair{Name: TargetDeploymentDefaultParameterName, Value: fromComponent.DeploymentName()}, toCapability) || updated
    98  	updated = AddCapabilityParameterIfNeeded(common.NameValuePair{Name: TargetPortDefaultParameterName, Value: fmt.Sprintf("%d", fromComponent.Spec.Port)}, toCapability) || updated
    99  	return updated
   100  }
   101  
   102  // AddCapabilityParameterIfNeeded adds the specified parameter to the specified capability, returning whether the capability was
   103  // updated as a result
   104  func AddCapabilityParameterIfNeeded(parameter common.NameValuePair, toCapability *v1beta1.Capability) (updated bool) {
   105  	value := parameter.Value
   106  	// try to see if that parameter was already set for that capability
   107  	found := false
   108  	for i, pair := range toCapability.Spec.Parameters {
   109  		if pair.Name == parameter.Name {
   110  			if pair.Value != value {
   111  				updated = true
   112  				toCapability.Spec.Parameters[i] = common.NameValuePair{Name: parameter.Name, Value: value}
   113  			}
   114  			found = true
   115  			break
   116  		}
   117  	}
   118  	// if we didn't find the parameter, add it
   119  	if !found {
   120  		updated = true
   121  		toCapability.Spec.Parameters = append(toCapability.Spec.Parameters, common.NameValuePair{Name: parameter.Name, Value: value})
   122  	}
   123  	return updated
   124  }
   125  
   126  type CapabilityConfig struct {
   127  	Name string                 `json:"name"`
   128  	Spec v1beta1.CapabilitySpec `json:"spec"`
   129  }
   130  
   131  type RequiredCapabilityConfig struct {
   132  	CapabilityConfig `json:",inline"`
   133  	BoundTo          string `json:"boundTo,omitempty"`
   134  	AutoBindable     bool   `json:"autoBindable,omitempty"`
   135  }
   136  type CapabilitiesConfig struct {
   137  	Requires []RequiredCapabilityConfig `json:"requires,omitempty"`
   138  	Provides []CapabilityConfig         `json:"provides,omitempty"`
   139  }
   140  
   141  const (
   142  	// PushReady means that component is ready to accept pushed code but might not be ready to accept requests yet
   143  	PushReady = "PushReady"
   144  	// Building means that the Build mode has been configured and that a build task is running
   145  	Building = "Building"
   146  )
   147  
   148  // ComponentStatus defines the observed state of Component
   149  // +k8s:openapi-gen=true
   150  type ComponentStatus struct {
   151  	common.Status `json:",inline"`
   152  }
   153  
   154  var PodGVK = schema.GroupVersionKind{
   155  	Group:   "",
   156  	Version: "v1",
   157  	Kind:    "Pod",
   158  }
   159  
   160  const PodNameAttributeKey = "PodName"
   161  
   162  func (in ComponentStatus) GetAssociatedPodName() string {
   163  	podCondition := in.GetConditionsWith(PodGVK)
   164  	if len(podCondition) != 1 {
   165  		return ""
   166  	}
   167  	return podCondition[0].GetAttribute(PodNameAttributeKey)
   168  }
   169  
   170  func (in ComponentStatus) IsPushReady() bool {
   171  	podCondition := in.GetConditionsWith(PodGVK)
   172  	if len(podCondition) != 1 {
   173  		return false
   174  	}
   175  	return podCondition[0].IsReady()
   176  }
   177  
   178  type Storage struct {
   179  	Name     string `json:"name,omitempty"`
   180  	Capacity string `json:"capacity,omitempty"`
   181  	Mode     string `json:"mode,omitempty"`
   182  }
   183  
   184  // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
   185  
   186  // Component is the Schema for the components API
   187  // +k8s:openapi-gen=true
   188  // +genclient
   189  type Component struct {
   190  	metav1.TypeMeta   `json:",inline"`
   191  	metav1.ObjectMeta `json:"metadata,omitempty"`
   192  
   193  	Spec   ComponentSpec   `json:"spec,omitempty"`
   194  	Status ComponentStatus `json:"status,omitempty"`
   195  }
   196  
   197  func (in *Component) GetGroupVersionKind() schema.GroupVersionKind {
   198  	return SchemeGroupVersion.WithKind(Kind)
   199  }
   200  
   201  func (in *Component) DeploymentName() string {
   202  	return in.DeploymentNameFor(in.Spec.DeploymentMode)
   203  }
   204  
   205  func (in *Component) DeploymentNameFor(mode DeploymentMode) string {
   206  	name := in.Name
   207  	if BuildDeploymentMode == mode {
   208  		return name + "-build"
   209  	}
   210  	return name
   211  }
   212  
   213  // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
   214  
   215  // ComponentList contains a list of Component
   216  type ComponentList struct {
   217  	metav1.TypeMeta `json:",inline"`
   218  	metav1.ListMeta `json:"metadata,omitempty"`
   219  	Items           []Component `json:"items"`
   220  }