Skip to content

Commit bb8ec6e

Browse files
authored
Merge pull request #7 from fluxcd/helmchart
Introduce HelmChart API and controller
2 parents 7a80807 + d378bd1 commit bb8ec6e

21 files changed

+859
-70
lines changed

.github/workflows/e2e.yaml

+4-2
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ jobs:
4343
run: |
4444
kubectl apply -f ./config/samples
4545
kubectl -n source-system rollout status deploy/source-controller --timeout=1m
46-
kubectl wait gitrepository/podinfo --for=condition=ready --timeout=1m
47-
kubectl wait helmrepository/podinfo --for=condition=ready --timeout=1m
46+
kubectl wait gitrepository/gitrepository-sample --for=condition=ready --timeout=1m
47+
kubectl wait helmrepository/helmrepository-sample --for=condition=ready --timeout=1m
48+
kubectl wait helmchart/helmchart-sample --for=condition=ready --timeout=1m
4849
kubectl -n source-system logs deploy/source-controller
4950
- name: Debug failure
5051
if: failure()
5152
run: |
5253
kubectl get gitrepositories -oyaml
5354
kubectl get helmrepositories -oyaml
55+
kubectl get helmcharts -oyaml
5456
kubectl -n source-system get all
5557
kubectl -n source-system logs deploy/source-controller

PROJECT

+3
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ resources:
77
- group: source
88
kind: HelmRepository
99
version: v1alpha1
10+
- group: source
11+
kind: HelmChart
12+
version: v1alpha1
1013
version: "2"

api/v1alpha1/gitrepository_types.go

+28-28
Original file line numberDiff line numberDiff line change
@@ -76,34 +76,6 @@ type GitRepositoryStatus struct {
7676
Artifact *Artifact `json:"artifact,omitempty"`
7777
}
7878

79-
// +kubebuilder:object:root=true
80-
// +kubebuilder:subresource:status
81-
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
82-
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
83-
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
84-
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
85-
86-
// GitRepository is the Schema for the gitrepositories API
87-
type GitRepository struct {
88-
metav1.TypeMeta `json:",inline"`
89-
metav1.ObjectMeta `json:"metadata,omitempty"`
90-
91-
Spec GitRepositorySpec `json:"spec,omitempty"`
92-
Status GitRepositoryStatus `json:"status,omitempty"`
93-
}
94-
95-
// GitRepositoryList contains a list of GitRepository
96-
// +kubebuilder:object:root=true
97-
type GitRepositoryList struct {
98-
metav1.TypeMeta `json:",inline"`
99-
metav1.ListMeta `json:"metadata,omitempty"`
100-
Items []GitRepository `json:"items"`
101-
}
102-
103-
func init() {
104-
SchemeBuilder.Register(&GitRepository{}, &GitRepositoryList{})
105-
}
106-
10779
const (
10880
GitOperationSucceedReason string = "GitOperationSucceed"
10981
GitOperationFailedReason string = "GitOperationFailed"
@@ -153,3 +125,31 @@ func GitRepositoryReadyMessage(repository GitRepository) string {
153125
}
154126
return ""
155127
}
128+
129+
// +kubebuilder:object:root=true
130+
// +kubebuilder:subresource:status
131+
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
132+
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
133+
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
134+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
135+
136+
// GitRepository is the Schema for the gitrepositories API
137+
type GitRepository struct {
138+
metav1.TypeMeta `json:",inline"`
139+
metav1.ObjectMeta `json:"metadata,omitempty"`
140+
141+
Spec GitRepositorySpec `json:"spec,omitempty"`
142+
Status GitRepositoryStatus `json:"status,omitempty"`
143+
}
144+
145+
// GitRepositoryList contains a list of GitRepository
146+
// +kubebuilder:object:root=true
147+
type GitRepositoryList struct {
148+
metav1.TypeMeta `json:",inline"`
149+
metav1.ListMeta `json:"metadata,omitempty"`
150+
Items []GitRepository `json:"items"`
151+
}
152+
153+
func init() {
154+
SchemeBuilder.Register(&GitRepository{}, &GitRepositoryList{})
155+
}

api/v1alpha1/helmchart_types.go

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
Copyright 2020 The Flux CD contributors.
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 v1alpha1
18+
19+
import (
20+
corev1 "k8s.io/api/core/v1"
21+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
)
23+
24+
// HelmChartSpec defines the desired state of HelmChart
25+
type HelmChartSpec struct {
26+
// The name of the Helm chart, as made available by the referenced
27+
// Helm repository.
28+
// +required
29+
Name string `json:"name"`
30+
31+
// The chart version semver expression, defaults to latest when
32+
// omitted.
33+
// +optional
34+
Version string `json:"version,omitempty"`
35+
36+
// The name of the HelmRepository the chart is available at.
37+
// +required
38+
HelmRepositoryRef corev1.LocalObjectReference `json:"helmRepositoryRef"`
39+
40+
// The interval at which to check the Helm repository for updates.
41+
// Defaults to the interval of the Helm repository.
42+
// +optional
43+
Interval *metav1.Duration `json:"interval,omitempty"`
44+
}
45+
46+
// IntervalOrDefault returns the defined interval on the HelmChartSpec
47+
// or the given default.
48+
func (s HelmChartSpec) IntervalOrDefault(interval metav1.Duration) metav1.Duration {
49+
if s.Interval == nil {
50+
return interval
51+
}
52+
return *s.Interval
53+
}
54+
55+
// HelmChartStatus defines the observed state of HelmChart
56+
type HelmChartStatus struct {
57+
// +optional
58+
Conditions []SourceCondition `json:"conditions,omitempty"`
59+
60+
// URL is the download link for the last chart pulled.
61+
// +optional
62+
URL string `json:"url,omitempty"`
63+
64+
// URI for the artifact of the latest successful chart pull.
65+
// +optional
66+
Artifact *Artifact `json:"artifact,omitempty"`
67+
}
68+
69+
const (
70+
// ChartPullFailedReason represents the fact that the pull of the
71+
// Helm chart failed.
72+
ChartPullFailedReason string = "ChartPullFailed"
73+
74+
// ChartPulLSucceededReason represents the fact that the pull of
75+
// the Helm chart succeeded.
76+
ChartPullSucceededReason string = "ChartPullSucceeded"
77+
)
78+
79+
func HelmChartReady(chart HelmChart, artifact Artifact, url, reason, message string) HelmChart {
80+
chart.Status.Conditions = []SourceCondition{
81+
{
82+
Type: ReadyCondition,
83+
Status: corev1.ConditionTrue,
84+
LastTransitionTime: metav1.Now(),
85+
Reason: reason,
86+
Message: message,
87+
},
88+
}
89+
chart.Status.URL = url
90+
91+
if chart.Status.Artifact != nil {
92+
if chart.Status.Artifact.Path != artifact.Path {
93+
chart.Status.Artifact = &artifact
94+
}
95+
} else {
96+
chart.Status.Artifact = &artifact
97+
}
98+
99+
return chart
100+
}
101+
102+
func HelmChartNotReady(chart HelmChart, reason, message string) HelmChart {
103+
chart.Status.Conditions = []SourceCondition{
104+
{
105+
Type: ReadyCondition,
106+
Status: corev1.ConditionFalse,
107+
LastTransitionTime: metav1.Now(),
108+
Reason: reason,
109+
Message: message,
110+
},
111+
}
112+
return chart
113+
}
114+
115+
func HelmChartReadyMessage(chart HelmChart) string {
116+
for _, condition := range chart.Status.Conditions {
117+
if condition.Type == ReadyCondition {
118+
return condition.Message
119+
}
120+
}
121+
return ""
122+
}
123+
124+
// +kubebuilder:object:root=true
125+
// +kubebuilder:subresource:status
126+
// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.spec.name`
127+
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.version`
128+
// +kubebuilder:printcolumn:name="Repository",type=string,JSONPath=`.spec.helmRepositoryRef.name`
129+
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
130+
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
131+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
132+
133+
// HelmChart is the Schema for the helmcharts API
134+
type HelmChart struct {
135+
metav1.TypeMeta `json:",inline"`
136+
metav1.ObjectMeta `json:"metadata,omitempty"`
137+
138+
Spec HelmChartSpec `json:"spec,omitempty"`
139+
Status HelmChartStatus `json:"status,omitempty"`
140+
}
141+
142+
// +kubebuilder:object:root=true
143+
144+
// HelmChartList contains a list of HelmChart
145+
type HelmChartList struct {
146+
metav1.TypeMeta `json:",inline"`
147+
metav1.ListMeta `json:"metadata,omitempty"`
148+
Items []HelmChart `json:"items"`
149+
}
150+
151+
func init() {
152+
SchemeBuilder.Register(&HelmChart{}, &HelmChartList{})
153+
}

api/v1alpha1/helmrepository_types.go

+28-28
Original file line numberDiff line numberDiff line change
@@ -47,34 +47,6 @@ type HelmRepositoryStatus struct {
4747
Artifact *Artifact `json:"artifact,omitempty"`
4848
}
4949

50-
// +kubebuilder:object:root=true
51-
// +kubebuilder:subresource:status
52-
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
53-
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
54-
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
55-
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
56-
57-
// HelmRepository is the Schema for the helmrepositories API
58-
type HelmRepository struct {
59-
metav1.TypeMeta `json:",inline"`
60-
metav1.ObjectMeta `json:"metadata,omitempty"`
61-
62-
Spec HelmRepositorySpec `json:"spec,omitempty"`
63-
Status HelmRepositoryStatus `json:"status,omitempty"`
64-
}
65-
66-
// HelmRepositoryList contains a list of HelmRepository
67-
// +kubebuilder:object:root=true
68-
type HelmRepositoryList struct {
69-
metav1.TypeMeta `json:",inline"`
70-
metav1.ListMeta `json:"metadata,omitempty"`
71-
Items []HelmRepository `json:"items"`
72-
}
73-
74-
func init() {
75-
SchemeBuilder.Register(&HelmRepository{}, &HelmRepositoryList{})
76-
}
77-
7850
const (
7951
// IndexationFailedReason represents the fact that the indexation
8052
// of the given Helm repository failed.
@@ -129,3 +101,31 @@ func HelmRepositoryReadyMessage(repository HelmRepository) string {
129101
}
130102
return ""
131103
}
104+
105+
// +kubebuilder:object:root=true
106+
// +kubebuilder:subresource:status
107+
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
108+
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
109+
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
110+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
111+
112+
// HelmRepository is the Schema for the helmrepositories API
113+
type HelmRepository struct {
114+
metav1.TypeMeta `json:",inline"`
115+
metav1.ObjectMeta `json:"metadata,omitempty"`
116+
117+
Spec HelmRepositorySpec `json:"spec,omitempty"`
118+
Status HelmRepositoryStatus `json:"status,omitempty"`
119+
}
120+
121+
// HelmRepositoryList contains a list of HelmRepository
122+
// +kubebuilder:object:root=true
123+
type HelmRepositoryList struct {
124+
metav1.TypeMeta `json:",inline"`
125+
metav1.ListMeta `json:"metadata,omitempty"`
126+
Items []HelmRepository `json:"items"`
127+
}
128+
129+
func init() {
130+
SchemeBuilder.Register(&HelmRepository{}, &HelmRepositoryList{})
131+
}

0 commit comments

Comments
 (0)