Skip to content

Commit a7645be

Browse files
committed
temporary: squash if this works
1 parent 8aa2c15 commit a7645be

File tree

7 files changed

+63
-84
lines changed

7 files changed

+63
-84
lines changed

pkg/controller/utils/statefulset.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,15 @@ import (
1111
"strings"
1212

1313
hivev1 "github.com/openshift/hive/apis/hive/v1"
14-
"github.com/openshift/hive/pkg/util/scheme"
1514

1615
"github.com/pkg/errors"
1716
log "github.com/sirupsen/logrus"
1817

1918
appsv1 "k8s.io/api/apps/v1"
20-
"k8s.io/apimachinery/pkg/runtime"
21-
"k8s.io/apimachinery/pkg/runtime/serializer"
2219
"k8s.io/apimachinery/pkg/types"
2320
"sigs.k8s.io/controller-runtime/pkg/client"
2421
)
2522

26-
var (
27-
appsScheme = scheme.GetScheme()
28-
appsCodecs = serializer.NewCodecFactory(appsScheme)
29-
)
30-
31-
// ReadStatefulsetOrDie converts a statefulset asset into an actual instance of a statefulset.
32-
func ReadStatefulsetOrDie(objBytes []byte) *appsv1.StatefulSet {
33-
requiredObj, err := runtime.Decode(appsCodecs.UniversalDecoder(appsv1.SchemeGroupVersion), objBytes)
34-
if err != nil {
35-
panic(err)
36-
}
37-
return requiredObj.(*appsv1.StatefulSet)
38-
}
39-
4023
// CalculateStatefulSetSpecHash returns a hash of the statefulset.Spec.
4124
func CalculateStatefulSetSpecHash(statefulset *appsv1.StatefulSet) (string, error) {
4225

pkg/operator/hive/apply.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ import (
1818
"github.com/openshift/hive/pkg/util/scheme"
1919
)
2020

21-
// RTOApplyOpt (runtime.Object apply option) modifies a runtime.Object in preparation for applying it.
22-
type RTOApplyOpt func(runtime.Object, log.FieldLogger) error
21+
// rtoApplyOpt (runtime.Object apply option) modifies a runtime.Object in preparation for applying it.
22+
type rtoApplyOpt func(runtime.Object, log.FieldLogger) error
2323

24-
// WithGarbageCollection returns a RTOApplyOpt that adds an owner reference to parent to the
24+
// withGarbageCollection returns a RTOApplyOpt that adds an owner reference to parent to the
2525
// runtime object so the latter gets cleaned up when the parent is deleted. Errors only happen
2626
// if the runtime object can't be interpreted as a metav1.Object or meta.Type.
27-
func WithGarbageCollection(parent v1.Object) RTOApplyOpt {
27+
func withGarbageCollection(parent v1.Object) rtoApplyOpt {
2828
return func(runtimeObj runtime.Object, hLog log.FieldLogger) error {
2929
obj, err := meta.Accessor(runtimeObj)
3030
if err != nil {
@@ -52,9 +52,9 @@ func WithGarbageCollection(parent v1.Object) RTOApplyOpt {
5252
}
5353
}
5454

55-
// WithNamespaceOverride returns a RTOApplyOpt that sets the namespace of the runtime object.
55+
// withNamespaceOverride returns a RTOApplyOpt that sets the namespace of the runtime object.
5656
// There are no error cases.
57-
func WithNamespaceOverride(namespaceOverride string) RTOApplyOpt {
57+
func withNamespaceOverride(namespaceOverride string) rtoApplyOpt {
5858
return func(runtimeObj runtime.Object, hLog log.FieldLogger) error {
5959
obj, err := meta.Accessor(runtimeObj)
6060
if err != nil {
@@ -66,11 +66,11 @@ func WithNamespaceOverride(namespaceOverride string) RTOApplyOpt {
6666
}
6767
}
6868

69-
// CRBWithSubjectNSOverride sets the namespace of each Subject to namespaceOverride if it is
69+
// crbWithSubjectNSOverride sets the namespace of each Subject to namespaceOverride if it is
7070
// - a ServiceAccount subject
7171
// - otherwise unset
7272
// Errors if the runtime object is not a *ClusterRoleBinding
73-
func CRBWithSubjectNSOverride(namespaceOverride string) RTOApplyOpt {
73+
func crbWithSubjectNSOverride(namespaceOverride string) rtoApplyOpt {
7474
return func(rto runtime.Object, hLog log.FieldLogger) error {
7575
rb, ok := rto.(*rbacv1.ClusterRoleBinding)
7676
if !ok {
@@ -85,49 +85,49 @@ func CRBWithSubjectNSOverride(namespaceOverride string) RTOApplyOpt {
8585
}
8686
}
8787

88-
// ToRuntimeObject defines a function that produces a runtime object. It is intended for use
88+
// toRuntimeObject defines a function that produces a runtime object. It is intended for use
8989
// in closures to supply such objects from different sources (asset paths, byte arrays) to
9090
// ApplyRuntimeObject().
91-
type ToRuntimeObject func(log.FieldLogger) (runtime.Object, error)
91+
type toRuntimeObject func(log.FieldLogger) (runtime.Object, error)
9292

93-
// Passthrough's func just returns the input runtime object.
94-
func Passthrough(rto runtime.Object) ToRuntimeObject {
93+
// passthrough's func just returns the input runtime object.
94+
func passthrough(rto runtime.Object) toRuntimeObject {
9595
return func(fl log.FieldLogger) (runtime.Object, error) {
9696
return rto, nil
9797
}
9898
}
9999

100-
// FromAssetPath's func loads a runtime object from a known asset path in bindata.
101-
func FromAssetPath(assetPath string) ToRuntimeObject {
100+
// fromAssetPath's func loads a runtime object from a known asset path in bindata.
101+
func fromAssetPath(assetPath string) toRuntimeObject {
102102
return func(hLog log.FieldLogger) (runtime.Object, error) {
103103
hLog.WithField("assetPath", assetPath).Info("loading runtime object from asset")
104104
return readRuntimeObject(assetPath)
105105
}
106106
}
107107

108-
// CRBFromAssetPath is a special case of FromAssetPath that returns a *ClusterRoleBinding
108+
// crbFromAssetPath is a special case of FromAssetPath that returns a *ClusterRoleBinding
109109
// (a specific instance of a runtime object) from a known asset path in bindata. Panics if
110110
// the asset is not a CRB, or if the asset can't be loaded from the specified path.
111-
func CRBFromAssetPath(roleBindingAssetPath string) ToRuntimeObject {
111+
func crbFromAssetPath(roleBindingAssetPath string) toRuntimeObject {
112112
return func(hLog log.FieldLogger) (runtime.Object, error) {
113113
hLog.WithField("assetPath", roleBindingAssetPath).Info("loading ClusterRoleBinding from asset")
114114
return resourceread.ReadClusterRoleBindingV1OrDie(assets.MustAsset(roleBindingAssetPath)), nil
115115
}
116116
}
117117

118-
// FromBytes produces a func that decodes a byte array into a runtime object.
119-
func FromBytes(assetBytes []byte) ToRuntimeObject {
118+
// fromBytes produces a func that decodes a byte array into a runtime object.
119+
func fromBytes(assetBytes []byte) toRuntimeObject {
120120
return func(hLog log.FieldLogger) (runtime.Object, error) {
121121
hLog.Info("decoding runtime object from bytes")
122122
return decodeRuntimeObject(assetBytes)
123123
}
124124
}
125125

126-
// ApplyRuntimeObject
126+
// applyRuntimeObject
127127
// - Executes rtoFactory to produce a runtime object.
128128
// - Modifies the runtime object according to opts.
129129
// - Applies the runtime object to the cluster via h.
130-
func ApplyRuntimeObject(h resource.Helper, rtoFactory ToRuntimeObject, hLog log.FieldLogger, opts ...RTOApplyOpt) (resource.ApplyResult, error) {
130+
func applyRuntimeObject(h resource.Helper, rtoFactory toRuntimeObject, hLog log.FieldLogger, opts ...rtoApplyOpt) (resource.ApplyResult, error) {
131131
requiredObj, err := rtoFactory(hLog)
132132
if err != nil {
133133
hLog.WithError(err).Error("failed to convert to runtime object")
@@ -142,23 +142,23 @@ func ApplyRuntimeObject(h resource.Helper, rtoFactory ToRuntimeObject, hLog log.
142142
return h.ApplyRuntimeObject(requiredObj, scheme.GetScheme())
143143
}
144144

145-
func DeleteAssetByPathWithNSOverride(h resource.Helper, assetPath, namespaceOverride string, hiveconfig *hivev1.HiveConfig) error {
145+
func deleteAssetByPathWithNSOverride(h resource.Helper, assetPath, namespaceOverride string, hiveconfig *hivev1.HiveConfig) error {
146146
requiredObj, err := readRuntimeObject(assetPath)
147147
if err != nil {
148148
return errors.Wrapf(err, "unable to decode asset: %s", assetPath)
149149
}
150-
return DeleteRuntimeObjectWithNSOverride(h, requiredObj, namespaceOverride, hiveconfig)
150+
return deleteRuntimeObjectWithNSOverride(h, requiredObj, namespaceOverride, hiveconfig)
151151
}
152152

153-
func DeleteAssetBytesWithNSOverride(h resource.Helper, assetBytes []byte, namespaceOverride string, hiveconfig *hivev1.HiveConfig) error {
153+
func deleteAssetBytesWithNSOverride(h resource.Helper, assetBytes []byte, namespaceOverride string, hiveconfig *hivev1.HiveConfig) error {
154154
rtObj, err := decodeRuntimeObject(assetBytes)
155155
if err != nil {
156156
return errors.Wrap(err, "unable to decode asset")
157157
}
158-
return DeleteRuntimeObjectWithNSOverride(h, rtObj, namespaceOverride, hiveconfig)
158+
return deleteRuntimeObjectWithNSOverride(h, rtObj, namespaceOverride, hiveconfig)
159159
}
160160

161-
func DeleteRuntimeObjectWithNSOverride(h resource.Helper, requiredObj runtime.Object, namespaceOverride string, hiveconfig *hivev1.HiveConfig) error {
161+
func deleteRuntimeObjectWithNSOverride(h resource.Helper, requiredObj runtime.Object, namespaceOverride string, hiveconfig *hivev1.HiveConfig) error {
162162
objA, _ := meta.Accessor(requiredObj)
163163
objT, _ := meta.TypeAccessor(requiredObj)
164164
if err := h.Delete(objT.GetAPIVersion(), objT.GetKind(), namespaceOverride, objA.GetName()); err != nil {

pkg/operator/hive/configmap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ func (r *ReconcileHiveConfig) deployConfigMap(hLog log.FieldLogger, h resource.H
339339
}
340340
}
341341

342-
result, err := ApplyRuntimeObject(h, Passthrough(cm), hLog, WithGarbageCollection(instance))
342+
result, err := applyRuntimeObject(h, passthrough(cm), hLog, withGarbageCollection(instance))
343343
if err != nil {
344344
cmLog.WithError(err).Error("error applying configmap")
345345
return "", err

pkg/operator/hive/hive.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (r *ReconcileHiveConfig) deployHive(hLog log.FieldLogger, h resource.Helper
6464
for _, asset := range assetsToClean {
6565
hLog.Infof("Deleting asset %s from old target namespace %s", asset, ns)
6666
// DeleteAssetWithNSOverride already no-ops for IsNotFound
67-
if err := DeleteAssetByPathWithNSOverride(h, asset, ns, instance); err != nil {
67+
if err := deleteAssetByPathWithNSOverride(h, asset, ns, instance); err != nil {
6868
return errors.Wrapf(err, "error deleting asset %s from old target namespace %s", asset, ns)
6969
}
7070
}
@@ -298,7 +298,7 @@ func (r *ReconcileHiveConfig) deployHive(hLog log.FieldLogger, h resource.Helper
298298

299299
// Load namespaced assets, decode them, set to our target namespace, and apply:
300300
for _, assetPath := range namespacedAssets {
301-
if _, err := ApplyRuntimeObject(h, FromAssetPath(assetPath), hLog, WithNamespaceOverride(hiveNSName), WithGarbageCollection(instance)); err != nil {
301+
if _, err := applyRuntimeObject(h, fromAssetPath(assetPath), hLog, withNamespaceOverride(hiveNSName), withGarbageCollection(instance)); err != nil {
302302
hLog.WithError(err).Error("error applying object with namespace override")
303303
return err
304304
}
@@ -311,7 +311,7 @@ func (r *ReconcileHiveConfig) deployHive(hLog log.FieldLogger, h resource.Helper
311311
"config/controllers/hive_controllers_role.yaml",
312312
}
313313
for _, a := range applyAssets {
314-
if _, err := ApplyRuntimeObject(h, FromAssetPath(a), hLog, WithGarbageCollection(instance)); err != nil {
314+
if _, err := applyRuntimeObject(h, fromAssetPath(a), hLog, withGarbageCollection(instance)); err != nil {
315315
hLog.WithField("asset", a).WithError(err).Error("error applying asset")
316316
return err
317317
}
@@ -324,7 +324,7 @@ func (r *ReconcileHiveConfig) deployHive(hLog log.FieldLogger, h resource.Helper
324324
}
325325
for _, crbAsset := range clusterRoleBindingAssets {
326326

327-
if _, err := ApplyRuntimeObject(h, CRBFromAssetPath(crbAsset), hLog, CRBWithSubjectNSOverride(hiveNSName), WithGarbageCollection(instance)); err != nil {
327+
if _, err := applyRuntimeObject(h, crbFromAssetPath(crbAsset), hLog, crbWithSubjectNSOverride(hiveNSName), withGarbageCollection(instance)); err != nil {
328328
hLog.WithError(err).Error("error applying ClusterRoleBinding with namespace override")
329329
return err
330330
}
@@ -345,7 +345,7 @@ func (r *ReconcileHiveConfig) deployHive(hLog log.FieldLogger, h resource.Helper
345345
if r.isOpenShift {
346346
hLog.Info("deploying OpenShift specific assets")
347347
for _, a := range openshiftSpecificAssets {
348-
_, err = ApplyRuntimeObject(h, FromAssetPath(a), hLog, WithGarbageCollection(instance))
348+
_, err = applyRuntimeObject(h, fromAssetPath(a), hLog, withGarbageCollection(instance))
349349
if err != nil {
350350
return err
351351
}
@@ -362,7 +362,7 @@ func (r *ReconcileHiveConfig) deployHive(hLog log.FieldLogger, h resource.Helper
362362
}
363363

364364
hiveDeployment.Namespace = hiveNSName
365-
result, err := ApplyRuntimeObject(h, Passthrough(hiveDeployment), hLog, WithGarbageCollection(instance))
365+
result, err := applyRuntimeObject(h, passthrough(hiveDeployment), hLog, withGarbageCollection(instance))
366366
if err != nil {
367367
hLog.WithError(err).Error("error applying deployment")
368368
return err
@@ -425,7 +425,7 @@ func (r *ReconcileHiveConfig) includeAdditionalCAs(hLog log.FieldLogger, h resou
425425
"ca.crt": additionalCA.Bytes(),
426426
},
427427
}
428-
result, err := ApplyRuntimeObject(h, Passthrough(caSecret), hLog, WithGarbageCollection(instance))
428+
result, err := applyRuntimeObject(h, passthrough(caSecret), hLog, withGarbageCollection(instance))
429429
if err != nil {
430430
hLog.WithError(err).Error("error applying additional cert secret")
431431
return err

pkg/operator/hive/hiveadmission.go

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@ import (
1212
controllerutils "github.com/openshift/hive/pkg/controller/utils"
1313
"github.com/openshift/hive/pkg/operator/assets"
1414
"github.com/openshift/hive/pkg/resource"
15-
"github.com/openshift/hive/pkg/util/scheme"
1615

1716
"github.com/openshift/library-go/pkg/operator/resource/resourceread"
1817

1918
admregv1 "k8s.io/api/admissionregistration/v1"
2019
corev1 "k8s.io/api/core/v1"
2120
"k8s.io/apimachinery/pkg/labels"
22-
"k8s.io/apimachinery/pkg/runtime"
23-
"k8s.io/apimachinery/pkg/runtime/serializer"
2421
"k8s.io/apimachinery/pkg/types"
2522
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
2623
)
@@ -73,7 +70,7 @@ func (r *ReconcileHiveConfig) deployHiveAdmission(hLog log.FieldLogger, h resour
7370
for _, asset := range assetsToClean {
7471
hLog.Infof("Deleting asset %s from old target namespace %s", asset, ns)
7572
// DeleteAssetWithNSOverride already no-ops for IsNotFound
76-
if err := DeleteAssetByPathWithNSOverride(h, asset, ns, instance); err != nil {
73+
if err := deleteAssetByPathWithNSOverride(h, asset, ns, instance); err != nil {
7774
return errors.Wrapf(err, "error deleting asset %s from old target namespace %s", asset, ns)
7875
}
7976
}
@@ -83,7 +80,7 @@ func (r *ReconcileHiveConfig) deployHiveAdmission(hLog log.FieldLogger, h resour
8380

8481
// Load namespaced assets, decode them, set to our target namespace, and apply:
8582
for _, assetPath := range namespacedAssets {
86-
if _, err := ApplyRuntimeObject(h, FromAssetPath(assetPath), hLog, WithNamespaceOverride(hiveNSName), WithGarbageCollection(instance)); err != nil {
83+
if _, err := applyRuntimeObject(h, fromAssetPath(assetPath), hLog, withNamespaceOverride(hiveNSName), withGarbageCollection(instance)); err != nil {
8784
hLog.WithError(err).Error("error applying object with namespace override")
8885
return err
8986
}
@@ -95,7 +92,7 @@ func (r *ReconcileHiveConfig) deployHiveAdmission(hLog log.FieldLogger, h resour
9592
"config/hiveadmission/hiveadmission_rbac_role.yaml",
9693
}
9794
for _, a := range applyAssets {
98-
if _, err := ApplyRuntimeObject(h, FromAssetPath(a), hLog, WithGarbageCollection(instance)); err != nil {
95+
if _, err := applyRuntimeObject(h, fromAssetPath(a), hLog, withGarbageCollection(instance)); err != nil {
9996
return err
10097
}
10198
}
@@ -105,7 +102,7 @@ func (r *ReconcileHiveConfig) deployHiveAdmission(hLog log.FieldLogger, h resour
105102
"config/hiveadmission/hiveadmission_rbac_role_binding.yaml",
106103
}
107104
for _, crbAsset := range clusterRoleBindingAssets {
108-
if _, err := ApplyRuntimeObject(h, CRBFromAssetPath(crbAsset), hLog, CRBWithSubjectNSOverride(hiveNSName), WithGarbageCollection(instance)); err != nil {
105+
if _, err := applyRuntimeObject(h, crbFromAssetPath(crbAsset), hLog, crbWithSubjectNSOverride(hiveNSName), withGarbageCollection(instance)); err != nil {
109106
hLog.WithError(err).Error("error applying ClusterRoleBinding with namespace override")
110107
return err
111108
}
@@ -153,31 +150,15 @@ func (r *ReconcileHiveConfig) deployHiveAdmission(hLog log.FieldLogger, h resour
153150
addConfigVolume(&hiveAdmDeployment.Spec.Template.Spec, r.supportedContractsConfigMapInfo(hLog), hiveAdmContainer)
154151
addReleaseImageVerificationConfigMapEnv(hiveAdmContainer, instance)
155152

156-
scheme := scheme.GetScheme()
157-
158153
validatingWebhooks := make([]*admregv1.ValidatingWebhookConfiguration, len(webhookAssets))
159154
for i, yaml := range webhookAssets {
160-
requiredObj, err := runtime.Decode(
161-
serializer.NewCodecFactory(scheme).
162-
UniversalDecoder(admregv1.SchemeGroupVersion), assets.MustAsset(yaml))
163-
if err != nil {
164-
panic(err)
165-
}
166-
167-
wh := requiredObj.(*admregv1.ValidatingWebhookConfiguration)
168-
validatingWebhooks[i] = wh
155+
validatingWebhooks[i] = readRuntimeObjectOrDie[*admregv1.ValidatingWebhookConfiguration](
156+
admregv1.SchemeGroupVersion, assets.MustAsset(yaml))
169157
}
170158

171159
hLog.Debug("reading apiservice")
172-
173-
requiredObj, err := runtime.Decode(
174-
serializer.NewCodecFactory(scheme).
175-
UniversalDecoder(
176-
apiregistrationv1.SchemeGroupVersion), assets.MustAsset("config/hiveadmission/apiservice.yaml"))
177-
if err != nil {
178-
panic(err)
179-
}
180-
apiService := requiredObj.(*apiregistrationv1.APIService)
160+
apiService := readRuntimeObjectOrDie[*apiregistrationv1.APIService](
161+
apiregistrationv1.SchemeGroupVersion, assets.MustAsset("config/hiveadmission/apiservice.yaml"))
181162
apiService.Spec.Service.Namespace = hiveNSName
182163

183164
err = r.injectCerts(apiService, validatingWebhooks, nil, hiveNSName, hLog)
@@ -207,22 +188,22 @@ func (r *ReconcileHiveConfig) deployHiveAdmission(hLog log.FieldLogger, h resour
207188
hiveAdmDeployment.Spec.Template.Spec.ImagePullSecrets = append(hiveAdmDeployment.Spec.Template.Spec.ImagePullSecrets, *ref)
208189
}
209190

210-
result, err := ApplyRuntimeObject(h, Passthrough(hiveAdmDeployment), hLog, WithGarbageCollection(instance))
191+
result, err := applyRuntimeObject(h, passthrough(hiveAdmDeployment), hLog, withGarbageCollection(instance))
211192
if err != nil {
212193
hLog.WithError(err).Error("error applying deployment")
213194
return err
214195
}
215196
hLog.WithField("result", result).Info("hiveadmission deployment applied")
216197

217-
result, err = ApplyRuntimeObject(h, Passthrough(apiService), hLog, WithGarbageCollection(instance))
198+
result, err = applyRuntimeObject(h, passthrough(apiService), hLog, withGarbageCollection(instance))
218199
if err != nil {
219200
hLog.WithError(err).Error("error applying apiservice")
220201
return err
221202
}
222203
hLog.Infof("apiservice applied (%s)", result)
223204

224205
for _, webhook := range validatingWebhooks {
225-
result, err = ApplyRuntimeObject(h, Passthrough(webhook), hLog, WithGarbageCollection(instance))
206+
result, err = applyRuntimeObject(h, passthrough(webhook), hLog, withGarbageCollection(instance))
226207
if err != nil {
227208
hLog.WithField("webhook", webhook.Name).WithError(err).Errorf("error applying validating webhook")
228209
return err

pkg/operator/hive/operatorutils.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,19 @@ import (
1111
corev1 "k8s.io/api/core/v1"
1212
apierrors "k8s.io/apimachinery/pkg/api/errors"
1313
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
"k8s.io/apimachinery/pkg/runtime"
1415
"k8s.io/apimachinery/pkg/runtime/schema"
16+
"k8s.io/apimachinery/pkg/runtime/serializer"
1517
"k8s.io/client-go/dynamic"
1618

1719
hivev1 "github.com/openshift/hive/apis/hive/v1"
1820
"github.com/openshift/hive/pkg/constants"
1921
controllerutils "github.com/openshift/hive/pkg/controller/utils"
22+
"github.com/openshift/hive/pkg/util/scheme"
2023
)
2124

25+
var appsCodecs = serializer.NewCodecFactory(scheme.GetScheme())
26+
2227
func GetHiveNamespace(config *hivev1.HiveConfig) string {
2328
if config.Spec.TargetNamespace == "" {
2429
return constants.DefaultHiveNamespace
@@ -95,3 +100,12 @@ func getImagePullSecretReference(config *hivev1.HiveConfig) *corev1.LocalObjectR
95100
}
96101
return nil
97102
}
103+
104+
func readRuntimeObjectOrDie[T any](sgv schema.GroupVersion, objBytes []byte) T {
105+
requiredObj, err := runtime.Decode(appsCodecs.UniversalDecoder(sgv), objBytes)
106+
if err != nil {
107+
panic(err)
108+
}
109+
return requiredObj.(T)
110+
111+
}

0 commit comments

Comments
 (0)