1 /* 2 Copyright 2022 The Flux authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package v1beta2 18 19 import ( 20 "time" 21 22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 24 "github.com/fluxcd/pkg/apis/acl" 25 "github.com/fluxcd/pkg/apis/meta" 26 27 apiv1 "github.com/fluxcd/source-controller/api/v1" 28 ) 29 30 // HelmChartKind is the string representation of a HelmChart. 31 const HelmChartKind = "HelmChart" 32 33 // HelmChartSpec specifies the desired state of a Helm chart. 34 type HelmChartSpec struct { 35 // Chart is the name or path the Helm chart is available at in the 36 // SourceRef. 37 // +required 38 Chart string `json:"chart"` 39 40 // Version is the chart version semver expression, ignored for charts from 41 // GitRepository and Bucket sources. Defaults to latest when omitted. 42 // +kubebuilder:default:=* 43 // +optional 44 Version string `json:"version,omitempty"` 45 46 // SourceRef is the reference to the Source the chart is available at. 47 // +required 48 SourceRef LocalHelmChartSourceReference `json:"sourceRef"` 49 50 // Interval at which the HelmChart SourceRef is checked for updates. 51 // This interval is approximate and may be subject to jitter to ensure 52 // efficient use of resources. 53 // +kubebuilder:validation:Type=string 54 // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" 55 // +required 56 Interval metav1.Duration `json:"interval"` 57 58 // ReconcileStrategy determines what enables the creation of a new artifact. 59 // Valid values are ('ChartVersion', 'Revision'). 60 // See the documentation of the values for an explanation on their behavior. 61 // Defaults to ChartVersion when omitted. 62 // +kubebuilder:validation:Enum=ChartVersion;Revision 63 // +kubebuilder:default:=ChartVersion 64 // +optional 65 ReconcileStrategy string `json:"reconcileStrategy,omitempty"` 66 67 // ValuesFiles is an alternative list of values files to use as the chart 68 // values (values.yaml is not included by default), expected to be a 69 // relative path in the SourceRef. 70 // Values files are merged in the order of this list with the last file 71 // overriding the first. Ignored when omitted. 72 // +optional 73 ValuesFiles []string `json:"valuesFiles,omitempty"` 74 75 // ValuesFile is an alternative values file to use as the default chart 76 // values, expected to be a relative path in the SourceRef. Deprecated in 77 // favor of ValuesFiles, for backwards compatibility the file specified here 78 // is merged before the ValuesFiles items. Ignored when omitted. 79 // +optional 80 // +deprecated 81 ValuesFile string `json:"valuesFile,omitempty"` 82 83 // IgnoreMissingValuesFiles controls whether to silently ignore missing values 84 // files rather than failing. 85 // +optional 86 IgnoreMissingValuesFiles bool `json:"ignoreMissingValuesFiles,omitempty"` 87 88 // Suspend tells the controller to suspend the reconciliation of this 89 // source. 90 // +optional 91 Suspend bool `json:"suspend,omitempty"` 92 93 // AccessFrom specifies an Access Control List for allowing cross-namespace 94 // references to this object. 95 // NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 96 // +optional 97 AccessFrom *acl.AccessFrom `json:"accessFrom,omitempty"` 98 99 // Verify contains the secret name containing the trusted public keys 100 // used to verify the signature and specifies which provider to use to check 101 // whether OCI image is authentic. 102 // This field is only supported when using HelmRepository source with spec.type 'oci'. 103 // Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. 104 // +optional 105 Verify *apiv1.OCIRepositoryVerification `json:"verify,omitempty"` 106 } 107 108 const ( 109 // ReconcileStrategyChartVersion reconciles when the version of the Helm chart is different. 110 ReconcileStrategyChartVersion string = "ChartVersion" 111 112 // ReconcileStrategyRevision reconciles when the Revision of the source is different. 113 ReconcileStrategyRevision string = "Revision" 114 ) 115 116 // LocalHelmChartSourceReference contains enough information to let you locate 117 // the typed referenced object at namespace level. 118 type LocalHelmChartSourceReference struct { 119 // APIVersion of the referent. 120 // +optional 121 APIVersion string `json:"apiVersion,omitempty"` 122 123 // Kind of the referent, valid values are ('HelmRepository', 'GitRepository', 124 // 'Bucket'). 125 // +kubebuilder:validation:Enum=HelmRepository;GitRepository;Bucket 126 // +required 127 Kind string `json:"kind"` 128 129 // Name of the referent. 130 // +required 131 Name string `json:"name"` 132 } 133 134 // HelmChartStatus records the observed state of the HelmChart. 135 type HelmChartStatus struct { 136 // ObservedGeneration is the last observed generation of the HelmChart 137 // object. 138 // +optional 139 ObservedGeneration int64 `json:"observedGeneration,omitempty"` 140 141 // ObservedSourceArtifactRevision is the last observed Artifact.Revision 142 // of the HelmChartSpec.SourceRef. 143 // +optional 144 ObservedSourceArtifactRevision string `json:"observedSourceArtifactRevision,omitempty"` 145 146 // ObservedChartName is the last observed chart name as specified by the 147 // resolved chart reference. 148 // +optional 149 ObservedChartName string `json:"observedChartName,omitempty"` 150 151 // ObservedValuesFiles are the observed value files of the last successful 152 // reconciliation. 153 // It matches the chart in the last successfully reconciled artifact. 154 // +optional 155 ObservedValuesFiles []string `json:"observedValuesFiles,omitempty"` 156 157 // Conditions holds the conditions for the HelmChart. 158 // +optional 159 Conditions []metav1.Condition `json:"conditions,omitempty"` 160 161 // URL is the dynamic fetch link for the latest Artifact. 162 // It is provided on a "best effort" basis, and using the precise 163 // BucketStatus.Artifact data is recommended. 164 // +optional 165 URL string `json:"url,omitempty"` 166 167 // Artifact represents the output of the last successful reconciliation. 168 // +optional 169 Artifact *apiv1.Artifact `json:"artifact,omitempty"` 170 171 meta.ReconcileRequestStatus `json:",inline"` 172 } 173 174 const ( 175 // ChartPullSucceededReason signals that the pull of the Helm chart 176 // succeeded. 177 ChartPullSucceededReason string = "ChartPullSucceeded" 178 179 // ChartPackageSucceededReason signals that the package of the Helm 180 // chart succeeded. 181 ChartPackageSucceededReason string = "ChartPackageSucceeded" 182 ) 183 184 // GetConditions returns the status conditions of the object. 185 func (in HelmChart) GetConditions() []metav1.Condition { 186 return in.Status.Conditions 187 } 188 189 // SetConditions sets the status conditions on the object. 190 func (in *HelmChart) SetConditions(conditions []metav1.Condition) { 191 in.Status.Conditions = conditions 192 } 193 194 // GetRequeueAfter returns the duration after which the source must be 195 // reconciled again. 196 func (in HelmChart) GetRequeueAfter() time.Duration { 197 return in.Spec.Interval.Duration 198 } 199 200 // GetArtifact returns the latest artifact from the source if present in the 201 // status sub-resource. 202 func (in *HelmChart) GetArtifact() *apiv1.Artifact { 203 return in.Status.Artifact 204 } 205 206 // GetValuesFiles returns a merged list of HelmChartSpec.ValuesFiles. 207 func (in *HelmChart) GetValuesFiles() []string { 208 valuesFiles := in.Spec.ValuesFiles 209 210 // Prepend the deprecated ValuesFile to the list 211 if in.Spec.ValuesFile != "" { 212 valuesFiles = append([]string{in.Spec.ValuesFile}, valuesFiles...) 213 } 214 return valuesFiles 215 } 216 217 // +genclient 218 // +kubebuilder:object:root=true 219 // +kubebuilder:resource:shortName=hc 220 // +kubebuilder:subresource:status 221 // +kubebuilder:deprecatedversion:warning="v1beta2 HelmChart is deprecated, upgrade to v1" 222 // +kubebuilder:printcolumn:name="Chart",type=string,JSONPath=`.spec.chart` 223 // +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.version` 224 // +kubebuilder:printcolumn:name="Source Kind",type=string,JSONPath=`.spec.sourceRef.kind` 225 // +kubebuilder:printcolumn:name="Source Name",type=string,JSONPath=`.spec.sourceRef.name` 226 // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" 227 // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="" 228 // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="" 229 230 // HelmChart is the Schema for the helmcharts API. 231 type HelmChart struct { 232 metav1.TypeMeta `json:",inline"` 233 metav1.ObjectMeta `json:"metadata,omitempty"` 234 235 Spec HelmChartSpec `json:"spec,omitempty"` 236 // +kubebuilder:default={"observedGeneration":-1} 237 Status HelmChartStatus `json:"status,omitempty"` 238 } 239 240 // HelmChartList contains a list of HelmChart objects. 241 // +kubebuilder:object:root=true 242 type HelmChartList struct { 243 metav1.TypeMeta `json:",inline"` 244 metav1.ListMeta `json:"metadata,omitempty"` 245 Items []HelmChart `json:"items"` 246 } 247 248 func init() { 249 SchemeBuilder.Register(&HelmChart{}, &HelmChartList{}) 250 } 251