Skip to content
This repository has been archived by the owner on Jun 8, 2022. It is now read-only.

Commit

Permalink
get CRD by discovery mechanism instead of get plural
Browse files Browse the repository at this point in the history
Signed-off-by: 天元 <[email protected]>
  • Loading branch information
wonderflow committed Oct 22, 2020
1 parent 7f067a0 commit 652249b
Show file tree
Hide file tree
Showing 22 changed files with 1,290 additions and 1,164 deletions.
6 changes: 5 additions & 1 deletion cmd/oam-kubernetes-runtime/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ func main() {

if useWebhook {
oamLog.Info("OAM webhook enabled, will serving at :" + strconv.Itoa(webhookPort))
webhook.Add(mgr)
if err = webhook.Add(mgr); err != nil {
oamLog.Error(err, "unable to setup the webhook for core controller")
os.Exit(1)
}

}

if err = appController.Setup(mgr, controllerArgs, logging.NewLogrLogger(oamLog)); err != nil {
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ go 1.13
require (
github.com/crossplane/crossplane-runtime v0.8.0
github.com/davecgh/go-spew v1.1.1
github.com/gertd/go-pluralize v0.1.7
github.com/ghodss/yaml v1.0.0
github.com/go-logr/logr v0.1.0
github.com/google/go-cmp v0.4.0
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gertd/go-pluralize v0.1.7 h1:RgvJTJ5W7olOoAks97BOwOlekBFsLEyh00W48Z6ZEZY=
github.com/gertd/go-pluralize v0.1.7/go.mod h1:O4eNeeIf91MHh1GJ2I47DNtaesm66NYvjYgAahcqSDQ=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ package applicationconfiguration

import (
"context"
"fmt"
"strconv"
"strings"
"time"

"github.com/crossplane/oam-kubernetes-runtime/pkg/oam"

"github.com/pkg/errors"
meta2 "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"

Expand All @@ -41,6 +42,7 @@ import (

"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"github.com/crossplane/oam-kubernetes-runtime/pkg/controller"
"github.com/crossplane/oam-kubernetes-runtime/pkg/oam"
)

const (
Expand Down Expand Up @@ -79,6 +81,10 @@ const (

// Setup adds a controller that reconciles ApplicationConfigurations.
func Setup(mgr ctrl.Manager, args controller.Args, l logging.Logger) error {
mapper, err := apiutil.NewDiscoveryRESTMapper(mgr.GetConfig())
if err != nil {
return fmt.Errorf("create discovery mapper fail %v", err)
}
name := "oam/" + strings.ToLower(v1alpha2.ApplicationConfigurationGroupKind)

return ctrl.NewControllerManagedBy(mgr).
Expand All @@ -89,7 +95,7 @@ func Setup(mgr ctrl.Manager, args controller.Args, l logging.Logger) error {
Logger: l,
RevisionLimit: args.RevisionLimit,
}).
Complete(NewReconciler(mgr,
Complete(NewReconciler(mgr, mapper,
WithLogger(l.WithValues("controller", name)),
WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name)))))
}
Expand Down Expand Up @@ -164,19 +170,21 @@ func WithPosthook(name string, hook ControllerHooks) ReconcilerOption {

// NewReconciler returns an OAMApplicationReconciler that reconciles ApplicationConfigurations
// by rendering and instantiating their Components and Traits.
func NewReconciler(m ctrl.Manager, o ...ReconcilerOption) *OAMApplicationReconciler {
func NewReconciler(m ctrl.Manager, mapper meta2.RESTMapper, o ...ReconcilerOption) *OAMApplicationReconciler {
r := &OAMApplicationReconciler{
client: m.GetClient(),
scheme: m.GetScheme(),
components: &components{
client: m.GetClient(),
mapper: mapper,
params: ParameterResolveFn(resolve),
workload: ResourceRenderFn(renderWorkload),
trait: ResourceRenderFn(renderTrait),
},
workloads: &workloads{
client: resource.NewAPIPatchingApplicator(m.GetClient()),
rawClient: m.GetClient(),
mapper: mapper,
},
gc: GarbageCollectorFn(eligible),
log: logging.NewNopLogger(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ func TestReconciler(t *testing.T) {

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
r := NewReconciler(tc.args.m, tc.args.o...)
r := NewReconciler(tc.args.m, nil, tc.args.o...)
got, err := r.Reconcile(reconcile.Request{})

if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
Expand Down Expand Up @@ -887,6 +887,8 @@ func TestDependency(t *testing.T) {
t.Fatal(err)
}

mapper := mock.NewMockMapper()

type args struct {
components []v1alpha2.ApplicationConfigurationComponent
wl *unstructured.Unstructured
Expand Down Expand Up @@ -1297,6 +1299,7 @@ func TestDependency(t *testing.T) {
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
c := components{
mapper: mapper,
client: &test.MockClient{
MockGet: test.MockGetFn(func(ctx context.Context, key client.ObjectKey, obj runtime.Object) error {
if obj.GetObjectKind().GroupVersionKind().Kind == "Workload" {
Expand Down Expand Up @@ -1623,7 +1626,7 @@ func TestUpdateStatus(t *testing.T) {
},
}

r := NewReconciler(m)
r := NewReconciler(m, nil)

ac := &v1alpha2.ApplicationConfiguration{}
err := r.client.Get(context.Background(), types.NamespacedName{Name: "example-appconfig"}, ac)
Expand Down
7 changes: 5 additions & 2 deletions pkg/controller/v1alpha2/applicationconfiguration/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package applicationconfiguration
import (
"context"

meta2 "k8s.io/apimachinery/pkg/api/meta"

runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
"github.com/crossplane/crossplane-runtime/pkg/meta"
Expand Down Expand Up @@ -76,6 +78,7 @@ func (fn WorkloadApplyFns) Finalize(ctx context.Context, ac *v1alpha2.Applicatio
type workloads struct {
client resource.Applicator
rawClient client.Client
mapper meta2.RESTMapper
}

func (a *workloads) Apply(ctx context.Context, status []v1alpha2.WorkloadStatus, w []Workload, ao ...resource.ApplyOption) error {
Expand Down Expand Up @@ -183,7 +186,7 @@ func findDereferencedScopes(statusScopes []v1alpha2.WorkloadScope, scopes []unst

func (a *workloads) applyScope(ctx context.Context, wl Workload, s unstructured.Unstructured, workloadRef runtimev1alpha1.TypedReference) error {
// get ScopeDefinition
scopeDefinition, err := util.FetchScopeDefinition(ctx, a.rawClient, &s)
scopeDefinition, err := util.FetchScopeDefinition(ctx, a.rawClient, a.mapper, &s)
if err != nil {
return errors.Wrapf(err, errFmtGetScopeDefinition, s.GetAPIVersion(), s.GetKind(), s.GetName())
}
Expand Down Expand Up @@ -237,7 +240,7 @@ func (a *workloads) applyScopeRemoval(ctx context.Context, namespace string, wr
return errors.Wrapf(err, errFmtApplyScope, s.Reference.APIVersion, s.Reference.Kind, s.Reference.Name)
}

scopeDefinition, err := util.FetchScopeDefinition(ctx, a.rawClient, &scopeObject)
scopeDefinition, err := util.FetchScopeDefinition(ctx, a.rawClient, a.mapper, &scopeObject)
if err != nil {
return errors.Wrapf(err, errFmtGetScopeDefinition, scopeObject.GetAPIVersion(), scopeObject.GetKind(), scopeObject.GetName())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"fmt"
"testing"

"github.com/crossplane/oam-kubernetes-runtime/pkg/oam/mock"

"github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
"github.com/crossplane/crossplane-runtime/pkg/resource"
Expand Down Expand Up @@ -318,7 +320,9 @@ func TestApplyWorkloads(t *testing.T) {

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
w := workloads{client: tc.client, rawClient: tc.rawClient}
mapper := mock.NewMockMapper()

w := workloads{client: tc.client, rawClient: tc.rawClient, mapper: mapper}
err := w.Apply(tc.args.ctx, tc.args.ws, tc.args.w)

if diff := cmp.Diff(tc.want, err, test.EquateErrors()); diff != "" {
Expand Down Expand Up @@ -463,7 +467,8 @@ func TestFinalizeWorkloadScopes(t *testing.T) {
for _, tc := range cases {
t.Run(tc.caseName, func(t *testing.T) {
acTest := ac
w := workloads{client: tc.client, rawClient: tc.rawClient}
mapper := mock.NewMockMapper()
w := workloads{client: tc.client, rawClient: tc.rawClient, mapper: mapper}
err := w.Finalize(ctx, &acTest)

if diff := cmp.Diff(tc.wantErr, err, test.EquateErrors()); diff != "" {
Expand Down
4 changes: 3 additions & 1 deletion pkg/controller/v1alpha2/applicationconfiguration/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/resource"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -83,6 +84,7 @@ var _ ComponentRenderer = &components{}

type components struct {
client client.Reader
mapper meta.RESTMapper
params ParameterResolver
workload ResourceRenderer
trait ResourceRenderer
Expand Down Expand Up @@ -211,7 +213,7 @@ func (r *components) renderTrait(ctx context.Context, ct v1alpha2.ComponentTrait

setTraitProperties(t, traitName, ac.GetNamespace(), ref)

traitDef, err := util.FetchTraitDefinition(ctx, r.client, t)
traitDef, err := util.FetchTraitDefinition(ctx, r.client, r.mapper, t)
if err != nil {
return nil, nil, errors.Wrapf(err, errFmtGetTraitDefinition, t.GetAPIVersion(), t.GetKind(), t.GetName())
}
Expand Down
37 changes: 27 additions & 10 deletions pkg/controller/v1alpha2/applicationconfiguration/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ import (
"encoding/json"
"testing"

"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"

"github.com/crossplane/oam-kubernetes-runtime/pkg/oam/mock"

"github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
Expand Down Expand Up @@ -498,7 +503,7 @@ func TestRenderComponents(t *testing.T) {
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
r := &components{tc.fields.client, tc.fields.params, tc.fields.workload, tc.fields.trait}
r := &components{tc.fields.client, mock.NewMockMapper(), tc.fields.params, tc.fields.workload, tc.fields.trait}
got, _, err := r.Render(tc.args.ctx, tc.args.ac)
if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
t.Errorf("\n%s\nr.Render(...): -want error, +got error:\n%s\n", tc.reason, diff)
Expand Down Expand Up @@ -844,7 +849,7 @@ func TestRenderTraitWithoutMetadataName(t *testing.T) {
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
r := &components{tc.fields.client, tc.fields.params, tc.fields.workload, tc.fields.trait}
r := &components{tc.fields.client, mock.NewMockMapper(), tc.fields.params, tc.fields.workload, tc.fields.trait}
got, _, _ := r.Render(tc.args.ctx, tc.args.ac)
if len(got) == 0 || len(got[0].Traits) == 0 || got[0].Traits[0].Object.GetName() != util.GenTraitName(componentName, ac.Spec.Components[0].Traits[0].DeepCopy()) {
t.Errorf("\n%s\nr.Render(...): -want error, +got error:\n%s\n", tc.reason, "Trait name is NOT"+
Expand All @@ -855,31 +860,43 @@ func TestRenderTraitWithoutMetadataName(t *testing.T) {
}

func TestGetDefinitionName(t *testing.T) {

tests := map[string]struct {
u *unstructured.Unstructured
exp string
reason string
u *unstructured.Unstructured
exp string
reason string
resource string
}{
"native resource": {
u: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
}},
exp: "deployments.apps",
reason: "native resource match",
exp: "deployments.apps",
reason: "native resource match",
resource: "deployments",
},
"extended resource": {
u: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "extend.oam.dev/v1alpha2",
"kind": "SimpleRolloutTrait",
}},
exp: "simplerollouttraits.extend.oam.dev",
reason: "extend resource match",
exp: "simplerollouttraits.extend.oam.dev",
reason: "extend resource match",
resource: "simplerollouttraits",
},
}
for name, ti := range tests {
t.Run(name, func(t *testing.T) {
got := util.GetDefinitionName(ti.u, "")
mapper := func(resource string) *mock.Mapper {
m := mock.NewMockMapper()
m.MockRESTMapping = func(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) {
return &meta.RESTMapping{Resource: schema.GroupVersionResource{Resource: resource}}, nil
}
return m
}(ti.resource)
got, err := util.GetDefinitionName(mapper, ti.u, "")
assert.NoError(t, err)
if got != ti.exp {
t.Errorf("%s getCRDName want %s got %s ", ti.reason, ti.exp, got)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"fmt"
"strings"

"k8s.io/apimachinery/pkg/api/meta"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"

cpv1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
"github.com/crossplane/crossplane-runtime/pkg/event"
"github.com/crossplane/crossplane-runtime/pkg/logging"
Expand Down Expand Up @@ -51,9 +54,14 @@ const (

// Setup adds a controller that reconciles ContainerizedWorkload.
func Setup(mgr ctrl.Manager, args controller.Args, log logging.Logger) error {
mapper, err := apiutil.NewDiscoveryRESTMapper(mgr.GetConfig())
if err != nil {
return err
}
reconciler := Reconciler{
Client: mgr.GetClient(),
DiscoveryClient: *discovery.NewDiscoveryClientForConfigOrDie(mgr.GetConfig()),
mapper: mapper,
log: ctrl.Log.WithName("ManualScalarTrait"),
record: event.NewAPIRecorder(mgr.GetEventRecorderFor("ManualScalarTrait")),
Scheme: mgr.GetScheme(),
Expand All @@ -65,6 +73,7 @@ func Setup(mgr ctrl.Manager, args controller.Args, log logging.Logger) error {
type Reconciler struct {
client.Client
discovery.DiscoveryClient
mapper meta.RESTMapper
log logr.Logger
record event.Recorder
Scheme *runtime.Scheme
Expand Down Expand Up @@ -105,7 +114,7 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
}

// Fetch the child resources list from the corresponding workload
resources, err := util.FetchWorkloadChildResources(ctx, mLog, r, workload)
resources, err := util.FetchWorkloadChildResources(ctx, mLog, r, r.mapper, workload)
if err != nil {
mLog.Error(err, "Error while fetching the workload child resources", "workload", workload.UnstructuredContent())
r.record.Event(eventObj, event.Warning(util.ErrFetchChildResources, err))
Expand Down Expand Up @@ -194,11 +203,14 @@ func (r *Reconciler) scaleResources(ctx context.Context, mLog logr.Logger,
func locateReplicaField(document openapi.Resources, res *unstructured.Unstructured) bool {
// this is the most common path for replicas fields
replicaFieldPath := []string{"spec", "replicas"}
g, v := util.APIVersion2GroupVersion(res.GetAPIVersion())
gv, err := schema.ParseGroupVersion(res.GetAPIVersion())
if err != nil {
return false
}
// we look up the resource schema definition by its GVK
schema := document.LookupResource(schema.GroupVersionKind{
Group: g,
Version: v,
Group: gv.Group,
Version: gv.Version,
Kind: res.GetKind(),
})
// we try to see if there is a spec.replicas fields in its definition
Expand Down
Loading

0 comments on commit 652249b

Please sign in to comment.