Skip to content

Commit 48ba490

Browse files
authored
Relax mc validations in the CLI to avoid errors (#13151)
Followup to #13061 When the CLI queried for Links in the cluster, we were assuming the CLI version matched the linkerd version in the cluster, and so we validated that all fields should be present. This change relaxes that assumption by setting defaults for the new fields `failureThreshold` and `timeout`, so we don't get an error for example when trying to run `linkerd multicluster uninstall` on a cluster with an older `Link` CRD.
1 parent 61cb8e3 commit 48ba490

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

pkg/multicluster/link.go

+23-3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ type (
5050
Selector metav1.LabelSelector
5151
RemoteDiscoverySelector metav1.LabelSelector
5252
}
53+
54+
ErrFieldMissing struct {
55+
Field string
56+
}
5357
)
5458

5559
// LinkGVR is the Group Version and Resource of the Link custom resource.
@@ -63,6 +67,10 @@ func (ps ProbeSpec) String() string {
6367
return fmt.Sprintf("ProbeSpec: {path: %s, port: %d, period: %s}", ps.Path, ps.Port, ps.Period)
6468
}
6569

70+
func (e *ErrFieldMissing) Error() string {
71+
return fmt.Sprintf("Field '%s' is missing", e.Field)
72+
}
73+
6674
// NewLink parses an unstructured link.multicluster.linkerd.io resource and
6775
// converts it to a structured internal representation.
6876
func NewLink(u unstructured.Unstructured) (Link, error) {
@@ -326,7 +334,13 @@ func newProbeSpec(obj map[string]interface{}) (ProbeSpec, error) {
326334

327335
failureThresholdStr, err := stringField(obj, "failureThreshold")
328336
if err != nil {
329-
return ProbeSpec{}, err
337+
var efm *ErrFieldMissing
338+
if errors.As(err, &efm) {
339+
// older Links might not have this field
340+
failureThresholdStr = fmt.Sprint(DefaultFailureThreshold)
341+
} else {
342+
return ProbeSpec{}, err
343+
}
330344
}
331345
failureThreshold, err := strconv.ParseUint(failureThresholdStr, 10, 32)
332346
if err != nil {
@@ -335,7 +349,13 @@ func newProbeSpec(obj map[string]interface{}) (ProbeSpec, error) {
335349

336350
timeoutStr, err := stringField(obj, "timeout")
337351
if err != nil {
338-
return ProbeSpec{}, err
352+
var efm *ErrFieldMissing
353+
if errors.As(err, &efm) {
354+
// older Links might not have this field
355+
timeoutStr = DefaultProbeTimeout
356+
} else {
357+
return ProbeSpec{}, err
358+
}
339359
}
340360
timeout, err := time.ParseDuration(timeoutStr)
341361
if err != nil {
@@ -368,7 +388,7 @@ func newProbeSpec(obj map[string]interface{}) (ProbeSpec, error) {
368388
func stringField(obj map[string]interface{}, key string) (string, error) {
369389
value, ok := obj[key]
370390
if !ok {
371-
return "", fmt.Errorf("Field '%s' is missing", key)
391+
return "", &ErrFieldMissing{Field: key}
372392
}
373393
str, ok := value.(string)
374394
if !ok {

0 commit comments

Comments
 (0)