-
Notifications
You must be signed in to change notification settings - Fork 820
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
- Loading branch information
1 parent
31f97ac
commit b639f25
Showing
2 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
185 changes: 185 additions & 0 deletions
185
pkg/resourceinterpreter/predefinedconfigurableinterpreter/configurable.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
package predefinedconfigurableinterpreter | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"sync" | ||
|
||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
|
||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" | ||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2" | ||
"github.com/karmada-io/karmada/resourcecustomizations" | ||
) | ||
|
||
const configurableInterpreterFile = "customizations.lua" | ||
|
||
// PredefinedConfigurableInterpreter interprets resources with build-in resource interpreter. | ||
type PredefinedConfigurableInterpreter struct { | ||
interpreters map[schema.GroupVersionKind]map[configv1alpha1.InterpreterOperation]string | ||
lock sync.RWMutex | ||
} | ||
|
||
// HookEnabled tells if any hook exist for specific resource type and operation. | ||
func (p *PredefinedConfigurableInterpreter) HookEnabled(objGVK schema.GroupVersionKind, operation configv1alpha1.InterpreterOperation) bool { | ||
_, enabled := p.getInterpreter(objGVK, operation) | ||
return enabled | ||
} | ||
|
||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica. | ||
func (p *PredefinedConfigurableInterpreter) GetReplicas(object *unstructured.Unstructured) (replica int32, replicaRequires *workv1alpha2.ReplicaRequirements, err error) { | ||
luaScript, exist := p.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationInterpretReplica) | ||
if !exist { | ||
return 0, &workv1alpha2.ReplicaRequirements{}, fmt.Errorf("predefined configurable %s interpreter for %q not found", configv1alpha1.InterpreterOperationInterpretReplica, object.GroupVersionKind()) | ||
} | ||
|
||
_ = luaScript | ||
// TODO | ||
return 0, nil, nil | ||
} | ||
|
||
// ReviseReplica revises the replica of the given object. | ||
func (p *PredefinedConfigurableInterpreter) ReviseReplica(object *unstructured.Unstructured, replica int64) (*unstructured.Unstructured, error) { | ||
luaScript, exist := p.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationReviseReplica) | ||
if !exist { | ||
return nil, fmt.Errorf("predefined configurable %s interpreter for %q not found", configv1alpha1.InterpreterOperationReviseReplica, object.GroupVersionKind()) | ||
} | ||
|
||
_ = luaScript | ||
// TODO | ||
return nil, nil | ||
} | ||
|
||
// Retain returns the objects that based on the "desired" object but with values retained from the "observed" object. | ||
func (p *PredefinedConfigurableInterpreter) Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error) { | ||
luaScript, exist := p.getInterpreter(desired.GroupVersionKind(), configv1alpha1.InterpreterOperationRetain) | ||
if !exist { | ||
return nil, fmt.Errorf("predefined configurable %s interpreter for %q not found", configv1alpha1.InterpreterOperationRetain, desired.GroupVersionKind()) | ||
} | ||
|
||
_ = luaScript | ||
// TODO | ||
return nil, nil | ||
} | ||
|
||
// AggregateStatus returns the objects that based on the 'object' but with status aggregated. | ||
func (p *PredefinedConfigurableInterpreter) AggregateStatus(object *unstructured.Unstructured, aggregatedStatusItems []workv1alpha2.AggregatedStatusItem) (*unstructured.Unstructured, error) { | ||
luaScript, exist := p.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationAggregateStatus) | ||
if !exist { | ||
return nil, fmt.Errorf("predefined configurable %s interpreter for %q not found", configv1alpha1.InterpreterOperationAggregateStatus, object.GroupVersionKind()) | ||
} | ||
|
||
_ = luaScript | ||
// TODO | ||
return nil, nil | ||
} | ||
|
||
// GetDependencies returns the dependent resources of the given object. | ||
func (p *PredefinedConfigurableInterpreter) GetDependencies(object *unstructured.Unstructured) (dependencies []configv1alpha1.DependentObjectReference, err error) { | ||
luaScript, exist := p.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationInterpretDependency) | ||
if !exist { | ||
return nil, fmt.Errorf("predefined configurable %s interpreter for operation %s not found", configv1alpha1.InterpreterOperationInterpretDependency, object.GroupVersionKind()) | ||
} | ||
|
||
_ = luaScript | ||
// TODO | ||
return nil, nil | ||
} | ||
|
||
// ReflectStatus returns the status of the object. | ||
func (p *PredefinedConfigurableInterpreter) ReflectStatus(object *unstructured.Unstructured) (status *runtime.RawExtension, err error) { | ||
luaScript, exist := p.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationInterpretStatus) | ||
if !exist { | ||
return nil, fmt.Errorf("predefined configurable %s interpreter for operation %s not found", configv1alpha1.InterpreterOperationInterpretStatus, object.GroupVersionKind()) | ||
} | ||
|
||
_ = luaScript | ||
// TODO | ||
return nil, nil | ||
} | ||
|
||
// InterpretHealth returns the health state of the object. | ||
func (p *PredefinedConfigurableInterpreter) InterpretHealth(object *unstructured.Unstructured) (healthy bool, err error) { | ||
luaScript, exist := p.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationInterpretHealth) | ||
if !exist { | ||
return false, fmt.Errorf("predefined configurable %s interpreter for %q not found", configv1alpha1.InterpreterOperationInterpretHealth, object.GroupVersionKind()) | ||
} | ||
|
||
_ = luaScript | ||
// TODO | ||
return false, nil | ||
} | ||
|
||
/* directory structure | ||
resource_customizations | ||
├── embed.go | ||
├── webapp.my.domain # Group | ||
│ └── v1 # Version | ||
│ └── Guestbook # Kind | ||
│ ├── customizations.lua # Fixed name | ||
│ ├── customizations_test.yaml | ||
│ └── testdata | ||
└── webapp2.my.domain | ||
└── v1 | ||
└── Guestbook | ||
├── customizations.lua | ||
├── customizations_test.yaml | ||
└── testdata | ||
*/ | ||
func (p *PredefinedConfigurableInterpreter) getPredefinedLuaScripts(objKey string, scriptFile string) (string, error) { | ||
data, err := resourcecustomizations.Embedded.ReadFile(filepath.Join(objKey, scriptFile)) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
return "", nil | ||
} | ||
return "", err | ||
} | ||
return string(data), nil | ||
} | ||
func (p *PredefinedConfigurableInterpreter) getConfigMapKey(gvk schema.GroupVersionKind) string { | ||
if gvk.Group == "" { | ||
return gvk.Kind | ||
} | ||
return fmt.Sprintf("%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind) | ||
} | ||
|
||
// getInterpreter returns interpreter for specific resource kind and operation. | ||
func (p *PredefinedConfigurableInterpreter) getInterpreter(kind schema.GroupVersionKind, operation configv1alpha1.InterpreterOperation) (string, bool) { | ||
p.lock.RLock() | ||
interpreter, ok := p.interpreters[kind][operation] | ||
p.lock.RUnlock() | ||
if !ok { | ||
luaScript, err := p.updateConfiguration(kind, operation) | ||
if err != nil || luaScript == "" { | ||
return "", false | ||
} | ||
interpreter, ok = luaScript, true | ||
} | ||
return interpreter, ok | ||
} | ||
|
||
func (p *PredefinedConfigurableInterpreter) updateConfiguration(kind schema.GroupVersionKind, operation configv1alpha1.InterpreterOperation) (string, error) { | ||
key := p.getConfigMapKey(kind) | ||
luaScript, err := p.getPredefinedLuaScripts(key, configurableInterpreterFile) | ||
if err != nil { | ||
return "", err | ||
} | ||
if luaScript == "" { | ||
return "", nil | ||
} | ||
p.lock.Lock() | ||
defer p.lock.Unlock() | ||
p.interpreters[kind][operation] = luaScript | ||
|
||
return luaScript, nil | ||
} | ||
|
||
// NewPredefinedConfigurableInterpreter return a new PredefinedConfigurableInterpreter. | ||
func NewPredefinedConfigurableInterpreter() *PredefinedConfigurableInterpreter { | ||
return &PredefinedConfigurableInterpreter{ | ||
interpreters: map[schema.GroupVersionKind]map[configv1alpha1.InterpreterOperation]string{}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package resourcecustomizations | ||
|
||
import ( | ||
"embed" | ||
) | ||
|
||
// Embedded contains embedded resource customization | ||
//go:embed * | ||
var Embedded embed.FS |