Skip to content

Commit 861343d

Browse files
committed
Put back deprecated types and hint to v1
Signed-off-by: Hidde Beydals <[email protected]>
1 parent ee7d9b3 commit 861343d

File tree

6 files changed

+550
-1
lines changed

6 files changed

+550
-1
lines changed

api/v1beta2/artifact_types.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
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+
"path"
21+
"regexp"
22+
"strings"
23+
24+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
)
26+
27+
// Artifact represents the output of a Source reconciliation.
28+
//
29+
// Deprecated: use Artifact from api/v1 instead. This type will be removed in
30+
// a future release.
31+
type Artifact struct {
32+
// Path is the relative file path of the Artifact. It can be used to locate
33+
// the file in the root of the Artifact storage on the local file system of
34+
// the controller managing the Source.
35+
// +required
36+
Path string `json:"path"`
37+
38+
// URL is the HTTP address of the Artifact as exposed by the controller
39+
// managing the Source. It can be used to retrieve the Artifact for
40+
// consumption, e.g. by another controller applying the Artifact contents.
41+
// +required
42+
URL string `json:"url"`
43+
44+
// Revision is a human-readable identifier traceable in the origin source
45+
// system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
46+
// +optional
47+
Revision string `json:"revision"`
48+
49+
// Checksum is the SHA256 checksum of the Artifact file.
50+
// Deprecated: use Artifact.Digest instead.
51+
// +optional
52+
Checksum string `json:"checksum,omitempty"`
53+
54+
// Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
55+
// +optional
56+
// +kubebuilder:validation:Pattern="^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$"
57+
Digest string `json:"digest,omitempty"`
58+
59+
// LastUpdateTime is the timestamp corresponding to the last update of the
60+
// Artifact.
61+
// +required
62+
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
63+
64+
// Size is the number of bytes in the file.
65+
// +optional
66+
Size *int64 `json:"size,omitempty"`
67+
68+
// Metadata holds upstream information such as OCI annotations.
69+
// +optional
70+
Metadata map[string]string `json:"metadata,omitempty"`
71+
}
72+
73+
// HasRevision returns if the given revision matches the current Revision of
74+
// the Artifact.
75+
func (in *Artifact) HasRevision(revision string) bool {
76+
if in == nil {
77+
return false
78+
}
79+
return TransformLegacyRevision(in.Revision) == TransformLegacyRevision(revision)
80+
}
81+
82+
// HasChecksum returns if the given checksum matches the current Checksum of
83+
// the Artifact.
84+
func (in *Artifact) HasChecksum(checksum string) bool {
85+
if in == nil {
86+
return false
87+
}
88+
return in.Checksum == checksum
89+
}
90+
91+
// ArtifactDir returns the artifact dir path in the form of
92+
// '<kind>/<namespace>/<name>'.
93+
func ArtifactDir(kind, namespace, name string) string {
94+
kind = strings.ToLower(kind)
95+
return path.Join(kind, namespace, name)
96+
}
97+
98+
// ArtifactPath returns the artifact path in the form of
99+
// '<kind>/<namespace>/name>/<filename>'.
100+
func ArtifactPath(kind, namespace, name, filename string) string {
101+
return path.Join(ArtifactDir(kind, namespace, name), filename)
102+
}
103+
104+
// TransformLegacyRevision transforms a "legacy" revision string into a "new"
105+
// revision string. It accepts the following formats:
106+
//
107+
// - main/5394cb7f48332b2de7c17dd8b8384bbc84b7e738
108+
// - feature/branch/5394cb7f48332b2de7c17dd8b8384bbc84b7e738
109+
// - HEAD/5394cb7f48332b2de7c17dd8b8384bbc84b7e738
110+
// - tag/55609ff9d959589ed917ce32e6bc0f0a36809565f308602c15c3668965979edc
111+
// - d52bde83c5b2bd0fa7910264e0afc3ac9cfe9b6636ca29c05c09742f01d5a4bd
112+
//
113+
// Which are transformed into the following formats respectively:
114+
//
115+
// - main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738
116+
// - feature/branch@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738
117+
// - sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738
118+
// - tag@sha256:55609ff9d959589ed917ce32e6bc0f0a36809565f308602c15c3668965979edc
119+
// - sha256:d52bde83c5b2bd0fa7910264e0afc3ac9cfe9b6636ca29c05c09742f01d5a4bd
120+
//
121+
// Deprecated, this function exists for backwards compatibility with existing
122+
// resources, and to provide a transition period. Will be removed in a future
123+
// release.
124+
func TransformLegacyRevision(rev string) string {
125+
if rev != "" && strings.LastIndex(rev, ":") == -1 {
126+
if i := strings.LastIndex(rev, "/"); i >= 0 {
127+
sha := rev[i+1:]
128+
if algo := determineSHAType(sha); algo != "" {
129+
if name := rev[:i]; name != "HEAD" {
130+
return name + "@" + algo + ":" + sha
131+
}
132+
return algo + ":" + sha
133+
}
134+
}
135+
if algo := determineSHAType(rev); algo != "" {
136+
return algo + ":" + rev
137+
}
138+
}
139+
return rev
140+
}
141+
142+
// isAlphaNumHex returns true if the given string only contains 0-9 and a-f
143+
// characters.
144+
var isAlphaNumHex = regexp.MustCompile(`^[0-9a-f]+$`).MatchString
145+
146+
// determineSHAType returns the SHA algorithm used to compute the provided hex.
147+
// The determination is heuristic and based on the length of the hex string. If
148+
// the size is not recognized, an empty string is returned.
149+
func determineSHAType(hex string) string {
150+
if isAlphaNumHex(hex) {
151+
switch len(hex) {
152+
case 40:
153+
return "sha1"
154+
case 64:
155+
return "sha256"
156+
}
157+
}
158+
return ""
159+
}

api/v1beta2/artifact_types_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
Copyright 2023 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 "testing"
20+
21+
func TestTransformLegacyRevision(t *testing.T) {
22+
tests := []struct {
23+
rev string
24+
want string
25+
}{
26+
{
27+
rev: "HEAD/5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
28+
want: "sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
29+
},
30+
{
31+
rev: "main/5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
32+
want: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
33+
},
34+
{
35+
rev: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
36+
want: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
37+
},
38+
{
39+
rev: "feature/branch/5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
40+
want: "feature/branch@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
41+
},
42+
{
43+
rev: "feature/branch@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
44+
want: "feature/branch@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
45+
},
46+
{
47+
rev: "5ac85ca617f3774baff4ae0a420b810b2546dbc9af9f346b1d55c5ed9873c55c",
48+
want: "sha256:5ac85ca617f3774baff4ae0a420b810b2546dbc9af9f346b1d55c5ed9873c55c",
49+
},
50+
{
51+
rev: "v1.0.0",
52+
want: "v1.0.0",
53+
},
54+
{
55+
rev: "v1.0.0-rc1",
56+
want: "v1.0.0-rc1",
57+
},
58+
{
59+
rev: "v1.0.0-rc1+metadata",
60+
want: "v1.0.0-rc1+metadata",
61+
},
62+
{
63+
rev: "arbitrary/revision",
64+
want: "arbitrary/revision",
65+
},
66+
{
67+
rev: "5394cb7f48332b2de7c17dd8b8384bbc84b7xxxx",
68+
want: "5394cb7f48332b2de7c17dd8b8384bbc84b7xxxx",
69+
},
70+
}
71+
for _, tt := range tests {
72+
t.Run(tt.rev, func(t *testing.T) {
73+
if got := TransformLegacyRevision(tt.rev); got != tt.want {
74+
t.Errorf("TransformLegacyRevision() = %v, want %v", got, tt.want)
75+
}
76+
})
77+
}
78+
}

api/v1beta2/condition_types.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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+
const SourceFinalizer = "finalizers.fluxcd.io"
20+
21+
const (
22+
// ArtifactInStorageCondition indicates the availability of the Artifact in
23+
// the storage.
24+
// If True, the Artifact is stored successfully.
25+
// This Condition is only present on the resource if the Artifact is
26+
// successfully stored.
27+
ArtifactInStorageCondition string = "ArtifactInStorage"
28+
29+
// ArtifactOutdatedCondition indicates the current Artifact of the Source
30+
// is outdated.
31+
// This is a "negative polarity" or "abnormal-true" type, and is only
32+
// present on the resource if it is True.
33+
ArtifactOutdatedCondition string = "ArtifactOutdated"
34+
35+
// SourceVerifiedCondition indicates the integrity verification of the
36+
// Source.
37+
// If True, the integrity check succeeded. If False, it failed.
38+
// This Condition is only present on the resource if the integrity check
39+
// is enabled.
40+
SourceVerifiedCondition string = "SourceVerified"
41+
42+
// FetchFailedCondition indicates a transient or persistent fetch failure
43+
// of an upstream Source.
44+
// If True, observations on the upstream Source revision may be impossible,
45+
// and the Artifact available for the Source may be outdated.
46+
// This is a "negative polarity" or "abnormal-true" type, and is only
47+
// present on the resource if it is True.
48+
FetchFailedCondition string = "FetchFailed"
49+
50+
// BuildFailedCondition indicates a transient or persistent build failure
51+
// of a Source's Artifact.
52+
// If True, the Source can be in an ArtifactOutdatedCondition.
53+
// This is a "negative polarity" or "abnormal-true" type, and is only
54+
// present on the resource if it is True.
55+
BuildFailedCondition string = "BuildFailed"
56+
57+
// StorageOperationFailedCondition indicates a transient or persistent
58+
// failure related to storage. If True, the reconciliation failed while
59+
// performing some filesystem operation.
60+
// This is a "negative polarity" or "abnormal-true" type, and is only
61+
// present on the resource if it is True.
62+
StorageOperationFailedCondition string = "StorageOperationFailed"
63+
)
64+
65+
// Reasons are provided as utility, and not part of the declarative API.
66+
const (
67+
// URLInvalidReason signals that a given Source has an invalid URL.
68+
URLInvalidReason string = "URLInvalid"
69+
70+
// AuthenticationFailedReason signals that a Secret does not have the
71+
// required fields, or the provided credentials do not match.
72+
AuthenticationFailedReason string = "AuthenticationFailed"
73+
74+
// VerificationError signals that the Source's verification
75+
// check failed.
76+
VerificationError string = "VerificationError"
77+
78+
// DirCreationFailedReason signals a failure caused by a directory creation
79+
// operation.
80+
DirCreationFailedReason string = "DirectoryCreationFailed"
81+
82+
// StatOperationFailedReason signals a failure caused by a stat operation on
83+
// a path.
84+
StatOperationFailedReason string = "StatOperationFailed"
85+
86+
// ReadOperationFailedReason signals a failure caused by a read operation.
87+
ReadOperationFailedReason string = "ReadOperationFailed"
88+
89+
// AcquireLockFailedReason signals a failure in acquiring lock.
90+
AcquireLockFailedReason string = "AcquireLockFailed"
91+
92+
// InvalidPathReason signals a failure caused by an invalid path.
93+
InvalidPathReason string = "InvalidPath"
94+
95+
// ArchiveOperationFailedReason signals a failure in archive operation.
96+
ArchiveOperationFailedReason string = "ArchiveOperationFailed"
97+
98+
// SymlinkUpdateFailedReason signals a failure in updating a symlink.
99+
SymlinkUpdateFailedReason string = "SymlinkUpdateFailed"
100+
101+
// ArtifactUpToDateReason signals that an existing Artifact is up-to-date
102+
// with the Source.
103+
ArtifactUpToDateReason string = "ArtifactUpToDate"
104+
105+
// CacheOperationFailedReason signals a failure in cache operation.
106+
CacheOperationFailedReason string = "CacheOperationFailed"
107+
)

api/v1beta2/source.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
"k8s.io/apimachinery/pkg/runtime"
23+
)
24+
25+
const (
26+
// SourceIndexKey is the key used for indexing objects based on their
27+
// referenced Source.
28+
SourceIndexKey string = ".metadata.source"
29+
)
30+
31+
// Source interface must be supported by all API types.
32+
// Source is the interface that provides generic access to the Artifact and
33+
// interval. It must be supported by all kinds of the source.toolkit.fluxcd.io
34+
// API group.
35+
//
36+
// Deprecated: use the Source interface from api/v1 instead. This type will be
37+
// removed in a future release.
38+
//
39+
// +k8s:deepcopy-gen=false
40+
type Source interface {
41+
runtime.Object
42+
// GetRequeueAfter returns the duration after which the source must be
43+
// reconciled again.
44+
GetRequeueAfter() time.Duration
45+
// GetArtifact returns the latest artifact from the source if present in
46+
// the status sub-resource.
47+
GetArtifact() *Artifact
48+
}

0 commit comments

Comments
 (0)