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 }