diff --git a/internal/pkg/rpaas/validation/manager.go b/internal/pkg/rpaas/validation/manager.go index 884eefd2..e19f0756 100644 --- a/internal/pkg/rpaas/validation/manager.go +++ b/internal/pkg/rpaas/validation/manager.go @@ -6,11 +6,14 @@ package validation import ( "context" "errors" + "fmt" "time" "github.com/tsuru/rpaas-operator/api/v1alpha1" "github.com/tsuru/rpaas-operator/internal/pkg/rpaas" + corev1 "k8s.io/api/core/v1" k8sErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -70,7 +73,56 @@ func (v *validationManager) UpdateBlock(ctx context.Context, instanceName string } func (v *validationManager) CreateExtraFiles(ctx context.Context, instanceName string, files ...rpaas.File) error { - return errNotImplementedYet + validation, err := v.validationCRD(ctx, instanceName) + if err != nil { + return err + } + + tempConfigMaps := []*corev1.ConfigMap{} + defer func() { + for _, configMap := range tempConfigMaps { + deleteErr := v.cli.Delete(ctx, configMap) + if deleteErr != nil { + // TODO: print err + } + } + + }() + + for _, f := range files { + _, found := findFileByName(validation.Spec.Files, f.Name) + if found { + return rpaas.ErrExtraFileAlreadyExists + } + } + + if validation.Spec.Files == nil { + validation.Spec.Files = make([]v1alpha1.File, 0, len(files)) + } + + for _, f := range files { + configMap, configMapErr := v.createTemporaryFileInConfigMap(ctx, validation, f) + if configMapErr != nil { + return configMapErr + } + + tempConfigMaps = append(tempConfigMaps, configMap) + + validation.Spec.Files = append(validation.Spec.Files, v1alpha1.File{ + Name: f.Name, + ConfigMap: &corev1.ConfigMapKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: configMap.Name}, + Key: f.Name, + }, + }) + } + + err = v.waitController(ctx, validation) + if err != nil { + return err + } + + return v.RpaasManager.CreateExtraFiles(ctx, instanceName, files...) } func (v *validationManager) DeleteExtraFiles(ctx context.Context, instanceName string, filenames ...string) error { @@ -78,7 +130,88 @@ func (v *validationManager) DeleteExtraFiles(ctx context.Context, instanceName s } func (v *validationManager) UpdateExtraFiles(ctx context.Context, instanceName string, files ...rpaas.File) error { - return errNotImplementedYet + validation, err := v.validationCRD(ctx, instanceName) + if err != nil { + return err + } + + tempConfigMaps := []*corev1.ConfigMap{} + defer func() { + for _, configMap := range tempConfigMaps { + deleteErr := v.cli.Delete(ctx, configMap) + if deleteErr != nil { + // TODO: print err + } + } + + }() + + for _, f := range files { + position, found := findFileByName(validation.Spec.Files, f.Name) + if !found { + return rpaas.ErrNoSuchExtraFile + } + + configMap, configMapErr := v.createTemporaryFileInConfigMap(ctx, validation, f) + if configMapErr != nil { + return configMapErr + } + + tempConfigMaps = append(tempConfigMaps, configMap) + + validation.Spec.Files[position] = v1alpha1.File{ + Name: f.Name, + ConfigMap: &corev1.ConfigMapKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: configMap.Name}, + Key: f.Name, + }, + } + } + + err = v.waitController(ctx, validation) + if err != nil { + return err + } + + return v.RpaasManager.UpdateExtraFiles(ctx, instanceName, files...) +} + +func (m *validationManager) createTemporaryFileInConfigMap(ctx context.Context, validation *v1alpha1.RpaasValidation, f rpaas.File) (*corev1.ConfigMap, error) { + newConfigMap := newConfigMapForFile(validation, f) + if err := m.cli.Create(ctx, newConfigMap); err != nil { + return nil, err + } + + return newConfigMap, nil + +} + +func newConfigMapForFile(validation *v1alpha1.RpaasValidation, f rpaas.File) *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: fmt.Sprintf("%s-validation-file-", validation.Name), + Namespace: validation.Namespace, + // we need TO discover UID of validation early + /*OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(validation, schema.GroupVersionKind{ + Group: v1alpha1.GroupVersion.Group, + Version: v1alpha1.GroupVersion.Version, + Kind: "RpaasValidation", + }), + },*/ + }, + BinaryData: map[string][]byte{f.Name: f.Content}, + } +} + +func findFileByName(files []v1alpha1.File, filename string) (int, bool) { + for i := range files { + if files[i].Name == filename { + return i, true + } + } + + return -1, false } func (v *validationManager) DeleteRoute(ctx context.Context, instanceName, path string) error {