mirror of
https://gitee.com/rainbond/Rainbond.git
synced 2024-12-02 03:37:46 +08:00
RepoReady condition
This commit is contained in:
parent
cf871ea270
commit
3333acd0db
@ -2,6 +2,10 @@ package main
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
rainbondv1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
|
||||
"github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
|
||||
k8sutil "github.com/goodrain/rainbond/util/k8s"
|
||||
@ -9,8 +13,6 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -36,19 +38,25 @@ func main() {
|
||||
},
|
||||
Spec: rainbondv1alpha1.HelmAppSpec{
|
||||
PreStatus: "",
|
||||
AppName: "",
|
||||
AppName: "rainbond-operator",
|
||||
Version: "v1.0.0",
|
||||
Revision: Int32(0),
|
||||
Values: "",
|
||||
AppStore: &rainbondv1alpha1.HelmAppStore{
|
||||
Version: "1111111",
|
||||
Name: "rainbond",
|
||||
URL: "https://openchart.goodrain.com/goodrain/rainbond",
|
||||
},
|
||||
},
|
||||
}
|
||||
if _, err := clientset.RainbondV1alpha1().HelmApps("rbd-system").Create(helmApp); err != nil {
|
||||
if _, err := clientset.RainbondV1alpha1().HelmApps("rbd-system").Create(context.Background(),
|
||||
helmApp, metav1.CreateOptions{}); err != nil {
|
||||
if !k8sErrors.IsAlreadyExists(err) {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
ctrl := helmapp.NewController(stopCh, restcfg, 5*time.Second)
|
||||
ctrl := helmapp.NewController(stopCh, restcfg, 5*time.Second, "/tmp/helm/repo/repositories.yaml", "/tmp/helm/cache")
|
||||
if err = ctrl.Start(); err != nil {
|
||||
logrus.Fatalf("start controller: %v", err)
|
||||
}
|
||||
|
@ -26,6 +26,12 @@ func (in *HelmAppStatus) GetCondition(t HelmAppConditionType) (int, *HelmAppCond
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// IsConditionTrue checks if the condition is ready or not based on the given condition type.
|
||||
func (in *HelmAppStatus) IsConditionTrue(t HelmAppConditionType) bool {
|
||||
idx, condition := in.GetCondition(t)
|
||||
return idx != -1 && condition.Status == corev1.ConditionTrue
|
||||
}
|
||||
|
||||
// SetCondition setups the given HelmApp condition.
|
||||
func (in *HelmAppStatus) SetCondition(c HelmAppCondition) {
|
||||
pos, cp := in.GetCondition(c.Type)
|
||||
@ -40,3 +46,44 @@ func (in *HelmAppStatus) SetCondition(c HelmAppCondition) {
|
||||
in.Conditions = append(in.Conditions, c)
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateCondition updates existing HelmApp condition or creates a new
|
||||
// one. Sets LastTransitionTime to now if the status has changed.
|
||||
// Returns true if HelmApp condition has changed or has been added.
|
||||
func (in *HelmAppStatus) UpdateCondition(condition *HelmAppCondition) bool {
|
||||
condition.LastTransitionTime = metav1.Now()
|
||||
// Try to find this HelmApp condition.
|
||||
conditionIndex, oldCondition := in.GetCondition(condition.Type)
|
||||
|
||||
if oldCondition == nil {
|
||||
// We are adding new HelmApp condition.
|
||||
in.Conditions = append(in.Conditions, *condition)
|
||||
return true
|
||||
}
|
||||
|
||||
// We are updating an existing condition, so we need to check if it has changed.
|
||||
if condition.Status == oldCondition.Status {
|
||||
condition.LastTransitionTime = oldCondition.LastTransitionTime
|
||||
}
|
||||
|
||||
isEqual := condition.Status == oldCondition.Status &&
|
||||
condition.Reason == oldCondition.Reason &&
|
||||
condition.Message == oldCondition.Message &&
|
||||
condition.LastTransitionTime.Equal(&oldCondition.LastTransitionTime)
|
||||
|
||||
in.Conditions[conditionIndex] = *condition
|
||||
// Return true if one of the fields have changed.
|
||||
return !isEqual
|
||||
}
|
||||
|
||||
func (in *HelmAppStatus) UpdateConditionStatus(conditionType HelmAppConditionType, conditionStatus corev1.ConditionStatus) {
|
||||
_, condition := in.GetCondition(conditionType)
|
||||
if condition != nil {
|
||||
condition.Status = conditionStatus
|
||||
in.UpdateCondition(condition)
|
||||
return
|
||||
}
|
||||
|
||||
condition = NewHelmAppCondition(conditionType, conditionStatus, "", "")
|
||||
in.UpdateCondition(condition)
|
||||
}
|
||||
|
@ -62,8 +62,10 @@ type HelmAppConditionType string
|
||||
|
||||
// These are valid conditions of helm app.
|
||||
const (
|
||||
// HelmAppDetected indicates whether the helm app has been detected.
|
||||
HelmAppDetected HelmAppConditionType = "Detected"
|
||||
// HelmAppRepoReady indicates whether the helm repository is ready.
|
||||
HelmAppRepoReady HelmAppConditionType = "RepoReady"
|
||||
// HelmAppChartReady indicates whether the chart is ready.
|
||||
HelmAppChartReady HelmAppConditionType = "ChartReady"
|
||||
// HelmAppDetected indicates whether the helm app has been installed.
|
||||
HelmAppInstalled HelmAppConditionType = "Installed"
|
||||
)
|
||||
@ -109,6 +111,10 @@ type HelmAppSpec struct {
|
||||
|
||||
// The values.yaml of the helm app, encoded by base64.
|
||||
Values string `json:"values"`
|
||||
|
||||
// The helm app store.
|
||||
// TODO: validation. not null
|
||||
AppStore *HelmAppStore `json:"appStore"`
|
||||
}
|
||||
|
||||
// HelmAppStore represents a helm repo.
|
||||
|
@ -109,6 +109,11 @@ func (in *HelmAppSpec) DeepCopyInto(out *HelmAppSpec) {
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.AppStore != nil {
|
||||
in, out := &in.AppStore, &out.AppStore
|
||||
*out = new(HelmAppStore)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmAppSpec.
|
||||
|
@ -61,7 +61,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||
if configShallowCopy.Burst <= 0 {
|
||||
return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
||||
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
||||
}
|
||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ import (
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
rainbondv1alpha1.AddToScheme,
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
@ -41,7 +43,7 @@ var helmappsResource = schema.GroupVersionResource{Group: "rainbond.goodrain.io"
|
||||
var helmappsKind = schema.GroupVersionKind{Group: "rainbond.goodrain.io", Version: "v1alpha1", Kind: "HelmApp"}
|
||||
|
||||
// Get takes name of the helmApp, and returns the corresponding helmApp object, and an error if there is any.
|
||||
func (c *FakeHelmApps) Get(name string, options v1.GetOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *FakeHelmApps) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(helmappsResource, c.ns, name), &v1alpha1.HelmApp{})
|
||||
|
||||
@ -52,7 +54,7 @@ func (c *FakeHelmApps) Get(name string, options v1.GetOptions) (result *v1alpha1
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of HelmApps that match those selectors.
|
||||
func (c *FakeHelmApps) List(opts v1.ListOptions) (result *v1alpha1.HelmAppList, err error) {
|
||||
func (c *FakeHelmApps) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.HelmAppList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(helmappsResource, helmappsKind, c.ns, opts), &v1alpha1.HelmAppList{})
|
||||
|
||||
@ -74,14 +76,14 @@ func (c *FakeHelmApps) List(opts v1.ListOptions) (result *v1alpha1.HelmAppList,
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested helmApps.
|
||||
func (c *FakeHelmApps) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
func (c *FakeHelmApps) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(helmappsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a helmApp and creates it. Returns the server's representation of the helmApp, and an error, if there is any.
|
||||
func (c *FakeHelmApps) Create(helmApp *v1alpha1.HelmApp) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *FakeHelmApps) Create(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.CreateOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(helmappsResource, c.ns, helmApp), &v1alpha1.HelmApp{})
|
||||
|
||||
@ -92,7 +94,7 @@ func (c *FakeHelmApps) Create(helmApp *v1alpha1.HelmApp) (result *v1alpha1.HelmA
|
||||
}
|
||||
|
||||
// Update takes the representation of a helmApp and updates it. Returns the server's representation of the helmApp, and an error, if there is any.
|
||||
func (c *FakeHelmApps) Update(helmApp *v1alpha1.HelmApp) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *FakeHelmApps) Update(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.UpdateOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(helmappsResource, c.ns, helmApp), &v1alpha1.HelmApp{})
|
||||
|
||||
@ -104,7 +106,7 @@ func (c *FakeHelmApps) Update(helmApp *v1alpha1.HelmApp) (result *v1alpha1.HelmA
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeHelmApps) UpdateStatus(helmApp *v1alpha1.HelmApp) (*v1alpha1.HelmApp, error) {
|
||||
func (c *FakeHelmApps) UpdateStatus(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.UpdateOptions) (*v1alpha1.HelmApp, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(helmappsResource, "status", c.ns, helmApp), &v1alpha1.HelmApp{})
|
||||
|
||||
@ -115,7 +117,7 @@ func (c *FakeHelmApps) UpdateStatus(helmApp *v1alpha1.HelmApp) (*v1alpha1.HelmAp
|
||||
}
|
||||
|
||||
// Delete takes name of the helmApp and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeHelmApps) Delete(name string, options *v1.DeleteOptions) error {
|
||||
func (c *FakeHelmApps) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(helmappsResource, c.ns, name), &v1alpha1.HelmApp{})
|
||||
|
||||
@ -123,15 +125,15 @@ func (c *FakeHelmApps) Delete(name string, options *v1.DeleteOptions) error {
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeHelmApps) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(helmappsResource, c.ns, listOptions)
|
||||
func (c *FakeHelmApps) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(helmappsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.HelmAppList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched helmApp.
|
||||
func (c *FakeHelmApps) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *FakeHelmApps) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.HelmApp, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(helmappsResource, c.ns, name, pt, data, subresources...), &v1alpha1.HelmApp{})
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
|
||||
@ -39,15 +40,15 @@ type HelmAppsGetter interface {
|
||||
|
||||
// HelmAppInterface has methods to work with HelmApp resources.
|
||||
type HelmAppInterface interface {
|
||||
Create(*v1alpha1.HelmApp) (*v1alpha1.HelmApp, error)
|
||||
Update(*v1alpha1.HelmApp) (*v1alpha1.HelmApp, error)
|
||||
UpdateStatus(*v1alpha1.HelmApp) (*v1alpha1.HelmApp, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha1.HelmApp, error)
|
||||
List(opts v1.ListOptions) (*v1alpha1.HelmAppList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.HelmApp, err error)
|
||||
Create(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.CreateOptions) (*v1alpha1.HelmApp, error)
|
||||
Update(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.UpdateOptions) (*v1alpha1.HelmApp, error)
|
||||
UpdateStatus(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.UpdateOptions) (*v1alpha1.HelmApp, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.HelmApp, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.HelmAppList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.HelmApp, err error)
|
||||
HelmAppExpansion
|
||||
}
|
||||
|
||||
@ -66,20 +67,20 @@ func newHelmApps(c *RainbondV1alpha1Client, namespace string) *helmApps {
|
||||
}
|
||||
|
||||
// Get takes name of the helmApp, and returns the corresponding helmApp object, and an error if there is any.
|
||||
func (c *helmApps) Get(name string, options v1.GetOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *helmApps) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
result = &v1alpha1.HelmApp{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("helmapps").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of HelmApps that match those selectors.
|
||||
func (c *helmApps) List(opts v1.ListOptions) (result *v1alpha1.HelmAppList, err error) {
|
||||
func (c *helmApps) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.HelmAppList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
@ -90,13 +91,13 @@ func (c *helmApps) List(opts v1.ListOptions) (result *v1alpha1.HelmAppList, err
|
||||
Resource("helmapps").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested helmApps.
|
||||
func (c *helmApps) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
func (c *helmApps) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
@ -107,87 +108,90 @@ func (c *helmApps) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
Resource("helmapps").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a helmApp and creates it. Returns the server's representation of the helmApp, and an error, if there is any.
|
||||
func (c *helmApps) Create(helmApp *v1alpha1.HelmApp) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *helmApps) Create(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.CreateOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
result = &v1alpha1.HelmApp{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("helmapps").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(helmApp).
|
||||
Do().
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a helmApp and updates it. Returns the server's representation of the helmApp, and an error, if there is any.
|
||||
func (c *helmApps) Update(helmApp *v1alpha1.HelmApp) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *helmApps) Update(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.UpdateOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
result = &v1alpha1.HelmApp{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("helmapps").
|
||||
Name(helmApp.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(helmApp).
|
||||
Do().
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *helmApps) UpdateStatus(helmApp *v1alpha1.HelmApp) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *helmApps) UpdateStatus(ctx context.Context, helmApp *v1alpha1.HelmApp, opts v1.UpdateOptions) (result *v1alpha1.HelmApp, err error) {
|
||||
result = &v1alpha1.HelmApp{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("helmapps").
|
||||
Name(helmApp.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(helmApp).
|
||||
Do().
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the helmApp and deletes it. Returns an error if one occurs.
|
||||
func (c *helmApps) Delete(name string, options *v1.DeleteOptions) error {
|
||||
func (c *helmApps) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("helmapps").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *helmApps) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
func (c *helmApps) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("helmapps").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched helmApp.
|
||||
func (c *helmApps) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.HelmApp, err error) {
|
||||
func (c *helmApps) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.HelmApp, err error) {
|
||||
result = &v1alpha1.HelmApp{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("helmapps").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do().
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
rainbondv1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
|
||||
@ -63,13 +64,13 @@ func NewFilteredHelmAppInformer(client versioned.Interface, namespace string, re
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.RainbondV1alpha1().HelmApps(namespace).List(options)
|
||||
return client.RainbondV1alpha1().HelmApps(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.RainbondV1alpha1().HelmApps(namespace).Watch(options)
|
||||
return client.RainbondV1alpha1().HelmApps(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&rainbondv1alpha1.HelmApp{},
|
||||
|
@ -28,8 +28,10 @@ import (
|
||||
)
|
||||
|
||||
// HelmAppLister helps list HelmApps.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type HelmAppLister interface {
|
||||
// List lists all HelmApps in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.HelmApp, err error)
|
||||
// HelmApps returns an object that can list and get HelmApps.
|
||||
HelmApps(namespace string) HelmAppNamespaceLister
|
||||
@ -60,10 +62,13 @@ func (s *helmAppLister) HelmApps(namespace string) HelmAppNamespaceLister {
|
||||
}
|
||||
|
||||
// HelmAppNamespaceLister helps list and get HelmApps.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type HelmAppNamespaceLister interface {
|
||||
// List lists all HelmApps in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.HelmApp, err error)
|
||||
// Get retrieves the HelmApp from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v1alpha1.HelmApp, error)
|
||||
HelmAppNamespaceListerExpansion
|
||||
}
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
|
@ -16,12 +16,13 @@ type Controller struct {
|
||||
controlLoop *ControlLoop
|
||||
}
|
||||
|
||||
func NewController(stopCh chan struct{}, restcfg *rest.Config, resyncPeriod time.Duration) *Controller {
|
||||
func NewController(stopCh chan struct{}, restcfg *rest.Config, resyncPeriod time.Duration,
|
||||
repoFile, repoCache string) *Controller {
|
||||
queue := workqueue.New()
|
||||
clientset := versioned.NewForConfigOrDie(restcfg)
|
||||
storer := NewStorer(clientset, resyncPeriod, queue)
|
||||
|
||||
controlLoop := NewControlLoop(storer, queue)
|
||||
controlLoop := NewControlLoop(clientset, storer, queue, repoFile, repoCache)
|
||||
|
||||
return &Controller{
|
||||
storer: storer,
|
||||
|
@ -1,6 +1,10 @@
|
||||
package helmapp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
|
||||
"github.com/goodrain/rainbond/worker/controllers/helmapp/helm"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"strings"
|
||||
|
||||
"github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
|
||||
@ -10,17 +14,26 @@ import (
|
||||
)
|
||||
|
||||
type ControlLoop struct {
|
||||
clientset versioned.Interface
|
||||
storer Storer
|
||||
workqueue workqueue.Interface
|
||||
repo *helm.Repo
|
||||
}
|
||||
|
||||
// NewControlLoop -
|
||||
func NewControlLoop(storer Storer,
|
||||
func NewControlLoop(clientset versioned.Interface,
|
||||
storer Storer,
|
||||
workqueue workqueue.Interface,
|
||||
repoFile string,
|
||||
repoCache string,
|
||||
) *ControlLoop {
|
||||
repo := helm.NewRepo(repoFile, repoCache)
|
||||
|
||||
return &ControlLoop{
|
||||
clientset: clientset,
|
||||
storer: storer,
|
||||
workqueue: workqueue,
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,8 +74,20 @@ func (c *ControlLoop) Reconcile(helmApp *v1alpha1.HelmApp) error {
|
||||
|
||||
status := NewStatus(helmApp.Status)
|
||||
|
||||
detector := NewDetector(status)
|
||||
detector.Detect()
|
||||
detector := NewDetector(helmApp, status, c.repo)
|
||||
err := detector.Detect()
|
||||
if err != nil {
|
||||
// TODO: create event
|
||||
return err
|
||||
}
|
||||
|
||||
helmApp.Status = status.HelmAppStatus
|
||||
// TODO: context
|
||||
if _, err := c.clientset.RainbondV1alpha1().HelmApps(helmApp.Namespace).
|
||||
UpdateStatus(context.Background(), helmApp, metav1.UpdateOptions{}); err != nil {
|
||||
// TODO: create event
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -1,12 +1,22 @@
|
||||
package helmapp
|
||||
|
||||
import (
|
||||
"github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
|
||||
"github.com/goodrain/rainbond/worker/controllers/helmapp/helm"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type Detector struct {
|
||||
helmApp *v1alpha1.HelmApp
|
||||
status *Status
|
||||
repo *helm.Repo
|
||||
}
|
||||
|
||||
func NewDetector(status *Status) *Detector {
|
||||
func NewDetector(helmApp *v1alpha1.HelmApp, status *Status, repo *helm.Repo) *Detector {
|
||||
return &Detector{
|
||||
helmApp: helmApp,
|
||||
status: status,
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +26,15 @@ func (d *Detector) Detect() error {
|
||||
}
|
||||
|
||||
// add repo
|
||||
if !d.status.IsConditionTrue(v1alpha1.HelmAppRepoReady) {
|
||||
appStore := d.helmApp.Spec.AppStore
|
||||
if err := d.repo.Add(appStore.Name, appStore.URL, "", ""); err != nil {
|
||||
d.status.SetCondition(*v1alpha1.NewHelmAppCondition(
|
||||
v1alpha1.HelmAppRepoReady, corev1.ConditionFalse, "RepoFailed", err.Error()))
|
||||
return err
|
||||
}
|
||||
d.status.UpdateConditionStatus(v1alpha1.HelmAppRepoReady, corev1.ConditionTrue)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -27,33 +27,24 @@ var deprecatedRepos = map[string]string{
|
||||
|
||||
// Repo -
|
||||
type Repo struct {
|
||||
name string
|
||||
url string
|
||||
username string
|
||||
password string
|
||||
forceUpdate bool
|
||||
|
||||
repoFile string
|
||||
repoCache string
|
||||
|
||||
forceUpdate bool
|
||||
insecureSkipTLSverify bool
|
||||
}
|
||||
|
||||
func NewRepo(name, url, username, password, repoFile, repoCache string) *Repo {
|
||||
// NewRepo creates a new repo.
|
||||
func NewRepo(repoFile, repoCache string) *Repo {
|
||||
return &Repo{
|
||||
name: name,
|
||||
url: url,
|
||||
username: username,
|
||||
password: password,
|
||||
forceUpdate: true,
|
||||
repoFile: repoFile,
|
||||
repoCache: repoCache,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Repo) Add() error {
|
||||
func (o *Repo) Add(name, url, username, password string) error {
|
||||
var buf bytes.Buffer
|
||||
err := o.add(&buf)
|
||||
err := o.add(&buf, name, url, username, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -64,11 +55,11 @@ func (o *Repo) Add() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Repo) add(out io.Writer) error {
|
||||
func (o *Repo) add(out io.Writer, name, url, username, password string) error {
|
||||
// Block deprecated repos
|
||||
for oldURL, newURL := range deprecatedRepos {
|
||||
if strings.Contains(o.url, oldURL) {
|
||||
return fmt.Errorf("repo %q is no longer available; try %q instead", o.url, newURL)
|
||||
if strings.Contains(url, oldURL) {
|
||||
return fmt.Errorf("repo %q is no longer available; try %q instead", url, newURL)
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,27 +92,27 @@ func (o *Repo) add(out io.Writer) error {
|
||||
}
|
||||
|
||||
c := repo.Entry{
|
||||
Name: o.name,
|
||||
URL: o.url,
|
||||
Username: o.username,
|
||||
Password: o.password,
|
||||
Name: name,
|
||||
URL: url,
|
||||
Username: username,
|
||||
Password: password,
|
||||
InsecureSkipTLSverify: o.insecureSkipTLSverify,
|
||||
}
|
||||
|
||||
// If the repo exists do one of two things:
|
||||
// 1. If the configuration for the name is the same continue without error
|
||||
// 2. When the config is different require --force-update
|
||||
if !o.forceUpdate && f.Has(o.name) {
|
||||
existing := f.Get(o.name)
|
||||
if !o.forceUpdate && f.Has(name) {
|
||||
existing := f.Get(name)
|
||||
if c != *existing {
|
||||
|
||||
// The input coming in for the name is different from what is already
|
||||
// configured. Return an error.
|
||||
return errors.Errorf("repository name (%s) already exists, please specify a different name", o.name)
|
||||
return errors.Errorf("repository name (%s) already exists, please specify a different name", name)
|
||||
}
|
||||
|
||||
// The add is idempotent so do nothing
|
||||
fmt.Fprintf(out, "%q already exists with the same configuration, skipping\n", o.name)
|
||||
fmt.Fprintf(out, "%q already exists with the same configuration, skipping\n", name)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -137,7 +128,7 @@ func (o *Repo) add(out io.Writer) error {
|
||||
r.CachePath = o.repoCache
|
||||
}
|
||||
if _, err := r.DownloadIndexFile(); err != nil {
|
||||
return errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", o.url)
|
||||
return errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", url)
|
||||
}
|
||||
|
||||
f.Update(&c)
|
||||
@ -145,6 +136,6 @@ func (o *Repo) add(out io.Writer) error {
|
||||
if err := f.WriteFile(o.repoFile, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(out, "%q has been added to your repositories\n", o.name)
|
||||
fmt.Fprintf(out, "%q has been added to your repositories\n", name)
|
||||
return nil
|
||||
}
|
||||
|
@ -7,11 +7,9 @@ import (
|
||||
)
|
||||
|
||||
func TestRepoAdd(t *testing.T) {
|
||||
repo := NewRepo(util.NewUUID(),
|
||||
"https://openchart.goodrain.com/goodrain/rainbond",
|
||||
"", "",
|
||||
repo := NewRepo(
|
||||
"/tmp/helm/repo/repositories.yaml",
|
||||
"/tmp/helm/cache")
|
||||
err := repo.Add()
|
||||
err := repo.Add(util.NewUUID(), "https://openchart.goodrain.com/goodrain/rainbond", "", "")
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
@ -11,16 +11,7 @@ type Status struct {
|
||||
|
||||
// NewStatus creates a new helm app status.
|
||||
func NewStatus(status v1alpha1.HelmAppStatus) *Status {
|
||||
idx, _ := status.GetCondition(v1alpha1.HelmAppDetected)
|
||||
if idx == -1 {
|
||||
status.SetCondition(*v1alpha1.NewHelmAppCondition(
|
||||
v1alpha1.HelmAppDetected,
|
||||
corev1.ConditionFalse,
|
||||
"",
|
||||
"",
|
||||
))
|
||||
}
|
||||
idx, _ = status.GetCondition(v1alpha1.HelmAppInstalled)
|
||||
idx, _ := status.GetCondition(v1alpha1.HelmAppInstalled)
|
||||
if idx == -1 {
|
||||
status.SetCondition(*v1alpha1.NewHelmAppCondition(
|
||||
v1alpha1.HelmAppInstalled,
|
||||
@ -35,6 +26,14 @@ func NewStatus(status v1alpha1.HelmAppStatus) *Status {
|
||||
}
|
||||
|
||||
func (s *Status) isDetected() bool {
|
||||
idx, condition := s.GetCondition(v1alpha1.HelmAppDetected)
|
||||
return idx != -1 && condition.Status == corev1.ConditionTrue
|
||||
types := []v1alpha1.HelmAppConditionType{
|
||||
v1alpha1.HelmAppRepoReady,
|
||||
v1alpha1.HelmAppChartReady,
|
||||
}
|
||||
for _, t := range types {
|
||||
if !s.IsConditionTrue(t) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user