Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Dev and Project labeling / refactoring labeling and annotations #5551

Merged
merged 3 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions pkg/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ import (

"github.com/pkg/errors"

applabels "github.com/redhat-developer/odo/pkg/application/labels"
"github.com/redhat-developer/odo/pkg/devfile/location"

"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/api/v2/pkg/devfile"
"github.com/devfile/library/pkg/devfile/parser"
parsercommon "github.com/devfile/library/pkg/devfile/parser/data/v2/common"
dfutil "github.com/devfile/library/pkg/util"

applabels "github.com/redhat-developer/odo/pkg/application/labels"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we keep the import grouping as it were?

componentlabels "github.com/redhat-developer/odo/pkg/component/labels"
"github.com/redhat-developer/odo/pkg/devfile/location"
"github.com/redhat-developer/odo/pkg/envinfo"
"github.com/redhat-developer/odo/pkg/kclient"
"github.com/redhat-developer/odo/pkg/libdevfile"
Expand All @@ -42,7 +43,6 @@ const componentRandomNamePartsMaxLen = 12
const componentNameMaxRetries = 3
const componentNameMaxLen = -1
const NotAvailable = "Not available"

const apiVersion = "odo.dev/v1alpha1"

// GetComponentDir returns source repo name
Expand Down Expand Up @@ -141,7 +141,7 @@ func ListDevfileComponents(client kclient.ClientInterface, selector string) (Com

// create a list of object metadata based on the component and application name (extracted from Deployment labels)
for _, elem := range deploymentList {
component, err := GetComponent(client, elem.Labels[componentlabels.ComponentLabel], elem.Labels[applabels.ApplicationLabel], client.GetCurrentNamespace())
component, err := GetComponent(client, elem.Labels[componentlabels.ComponentKubernetesInstanceLabel], elem.Labels[applabels.ApplicationLabel], client.GetCurrentNamespace())
if err != nil {
return ComponentList{}, errors.Wrap(err, "Unable to get component")
}
Expand Down Expand Up @@ -231,6 +231,7 @@ func GetLanguageFromDevfileMetadata(metadata devfile.DevfileMetadata) string {

func getComponentFrom(info localConfigProvider.LocalConfigProvider, componentType string) (Component, error) {
if info.Exists() {

component := newComponentWithType(info.GetName(), componentType)

component.Namespace = info.GetNamespace()
Expand Down Expand Up @@ -328,8 +329,9 @@ func Exists(client kclient.ClientInterface, componentName, applicationName strin
return false, nil
}

func GetComponentState(client kclient.ClientInterface, componentName, applicationName string) State {
// first check if a deployment exists
// GetComponentState ...
cdrage marked this conversation as resolved.
Show resolved Hide resolved
func GetComponentState(client kclient.ClientInterface, componentName, applicationName string) string {
// Check to see if the deployment has been pushed or not
c, err := GetPushedComponent(client, componentName, applicationName)
if err != nil {
return StateTypeUnknown
Expand Down Expand Up @@ -413,13 +415,14 @@ func getRemoteComponentMetadata(client kclient.ClientInterface, componentName st
// Annotations
component.Annotations = fromCluster.GetAnnotations()

// Mark the component status as pushed
component.Status.State = componentlabels.ComponentPushedName
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably use StateTypePushed from types.go


// Labels
component.Labels = fromCluster.GetLabels()

component.Namespace = client.GetCurrentNamespace()
component.Spec.App = applicationName
component.Spec.Env = filteredEnv
component.Status.State = StateTypePushed

return component, nil
}
Expand Down Expand Up @@ -476,7 +479,7 @@ func setLinksServiceNames(client kclient.ClientInterface, linkedSecrets []Secret

serviceCompMap := make(map[string]string)
for _, gotService := range services {
serviceCompMap[gotService.Labels[componentlabels.ComponentLabel]] = gotService.Name
serviceCompMap[gotService.Labels[componentlabels.ComponentKubernetesInstanceLabel]] = gotService.Name
}

for _, secret := range secrets {
Expand Down
2 changes: 1 addition & 1 deletion pkg/component/component_full_description.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (cfd *ComponentFullDescription) fillEmptyFields(componentDesc Component, co
// NewComponentFullDescriptionFromClientAndLocalConfigProvider gets the complete description of the component from cluster
func NewComponentFullDescriptionFromClientAndLocalConfigProvider(client kclient.ClientInterface, envInfo *envinfo.EnvSpecificInfo, componentName string, applicationName string, projectName string, context string) (*ComponentFullDescription, error) {
cfd := &ComponentFullDescription{}
var state State
var state string
if client == nil {
state = StateTypeUnknown
} else {
Expand Down
24 changes: 13 additions & 11 deletions pkg/component/component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

devfilepkg "github.com/devfile/api/v2/pkg/devfile"
"github.com/kylelemons/godebug/pretty"

v1 "k8s.io/api/apps/v1"

Expand Down Expand Up @@ -146,13 +147,13 @@ func TestList(t *testing.T) {
*testingutil.CreateFakeDeployment("comp1"),
}}

deploymentList.Items[0].Labels[componentlabels.ComponentTypeLabel] = "nodejs"
deploymentList.Items[0].Labels[componentlabels.ComponentKubernetesNameLabel] = "nodejs"
deploymentList.Items[0].Annotations = map[string]string{
componentlabels.ComponentTypeAnnotation: "nodejs",
componentlabels.ComponentProjectTypeAnnotation: "nodejs",
}
deploymentList.Items[1].Labels[componentlabels.ComponentTypeLabel] = "wildfly"
deploymentList.Items[1].Labels[componentlabels.ComponentKubernetesNameLabel] = "wildfly"
deploymentList.Items[1].Annotations = map[string]string{
componentlabels.ComponentTypeAnnotation: "wildfly",
componentlabels.ComponentProjectTypeAnnotation: "wildfly",
}
tests := []struct {
name string
Expand Down Expand Up @@ -223,6 +224,7 @@ func TestList(t *testing.T) {
}

if !reflect.DeepEqual(tt.output, results) {
t.Errorf("Unexpected output, see the diff in results: %s", pretty.Compare(tt.output, results))
t.Errorf("expected output:\n%#v\n\ngot:\n%#v", tt.output, results)
}
})
Expand Down Expand Up @@ -472,7 +474,7 @@ func TestGetComponentTypeFromDevfileMetadata(t *testing.T) {
}
}

func getFakeComponent(compName, namespace, appName, compType string, state State) Component {
func getFakeComponent(compName, namespace, appName, compType string, state string) Component {
return Component{
TypeMeta: metav1.TypeMeta{
Kind: "Component",
Expand All @@ -482,14 +484,14 @@ func getFakeComponent(compName, namespace, appName, compType string, state State
Name: compName,
Namespace: namespace,
Labels: map[string]string{
applabels.App: appName,
applabels.ManagedBy: "odo",
applabels.ApplicationLabel: appName,
componentlabels.ComponentLabel: compName,
componentlabels.ComponentTypeLabel: compType,
applabels.App: appName,
applabels.ManagedBy: "odo",
applabels.ApplicationLabel: appName,
componentlabels.ComponentKubernetesInstanceLabel: compName,
componentlabels.ComponentKubernetesNameLabel: compType,
},
Annotations: map[string]string{
componentlabels.ComponentTypeAnnotation: compType,
componentlabels.ComponentProjectTypeAnnotation: compType,
},
},
Spec: ComponentSpec{
Expand Down
33 changes: 23 additions & 10 deletions pkg/component/labels/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,43 @@ import (
"github.com/redhat-developer/odo/pkg/util"
)

// ComponentLabel is a label key used to identify the component name
const ComponentLabel = "app.kubernetes.io/instance"
// ComponentKubernetesInstanceLabel is a label key used to identify the component name
const ComponentKubernetesInstanceLabel = "app.kubernetes.io/instance"

// ComponentTypeLabel is Kubernetes label that identifies the type of a component being used
const ComponentTypeLabel = "app.kubernetes.io/name"
// ComponentKubernetesNameLabel is Kubernetes label that identifies the type of a component being used
const ComponentKubernetesNameLabel = "app.kubernetes.io/name"

const ComponentTypeAnnotation = "odo.dev/project-type"
// ComponentUnknownLabel is the label that is used to display something we do not know
const ComponentUnknownLabel = "<unknown>"

// ComponentDeployLabel ...
const ComponentDeployLabel = "Deploy"
// KubernetesManagedByLabel ...
cdrage marked this conversation as resolved.
Show resolved Hide resolved
const KubernetesManagedByLabel = "app.kubernetes.io/managed-by"

// ComponentModeLabel ...
const ComponentModeLabel = "odo.dev/mode"
cdrage marked this conversation as resolved.
Show resolved Hide resolved

// ComponentProjectTypeLabel ...
const ComponentProjectTypeLabel = "odo.dev/project-type"
// ComponentDevName ...
const ComponentDevName = "Dev"

// ComponentDeployName ...
const ComponentDeployName = "Deploy"

// ComponentNoneName ...
const ComponentNoneName = "None"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used anywhere.


// ComponentPushedName ...
const ComponentPushedName = "Pushed"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used as a label or its value it should not be in this file.

Similar constant is already defined in pkg/component/types.go


// ComponentProjectTypeAnnotation ...
const ComponentProjectTypeAnnotation = "odo.dev/project-type"

// GetLabels return labels that should be applied to every object for given component in active application
// additional labels are used only for creating object
// if you are creating something use additional=true
// if you need labels to filter component then use additional=false
func GetLabels(componentName string, applicationName string, additional bool) map[string]string {
labels := applabels.GetLabels(applicationName, additional)
labels[ComponentLabel] = componentName
labels[ComponentKubernetesInstanceLabel] = componentName
return labels
}

Expand Down
14 changes: 7 additions & 7 deletions pkg/component/labels/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ func TestGetLabels(t *testing.T) {
additional: false,
},
want: map[string]string{
applabels.ApplicationLabel: "applicationame",
ComponentLabel: "componentname",
applabels.ApplicationLabel: "applicationame",
ComponentKubernetesInstanceLabel: "componentname",
},
}, {
name: "everything with additional",
Expand All @@ -38,11 +38,11 @@ func TestGetLabels(t *testing.T) {
additional: true,
},
want: map[string]string{
applabels.ApplicationLabel: "applicationame",
applabels.App: "applicationame",
applabels.ManagedBy: "odo",
applabels.ManagerVersion: version.VERSION,
ComponentLabel: "componentname",
applabels.ApplicationLabel: "applicationame",
applabels.App: "applicationame",
applabels.ManagedBy: "odo",
applabels.ManagerVersion: version.VERSION,
ComponentKubernetesInstanceLabel: "componentname",
},
},
}
Expand Down
16 changes: 9 additions & 7 deletions pkg/component/pushed_component.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
v1 "k8s.io/api/apps/v1"
v12 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/klog"
)

type provider interface {
Expand Down Expand Up @@ -143,22 +142,24 @@ func (d devfileComponent) GetEnvVars() []v12.EnvVar {
func (d devfileComponent) GetLabels() map[string]string {
return d.d.Labels
}

func (d devfileComponent) GetAnnotations() map[string]string {
return d.d.Annotations
}

func (d devfileComponent) GetName() string {
return d.d.Labels[componentlabels.ComponentLabel]
return d.d.Labels[componentlabels.ComponentKubernetesInstanceLabel]
}

func getType(component provider) (string, error) {
if componentType, ok := component.GetAnnotations()[componentlabels.ComponentTypeAnnotation]; ok {

// For backwards compatibility with previously deployed components that could be non-odo, check the label first
// then check to see if there is an annotation with the project type
if componentType, ok := component.GetLabels()[componentlabels.ComponentProjectTypeAnnotation]; ok {
return componentType, nil
} else if componentType, ok = component.GetAnnotations()[componentlabels.ComponentProjectTypeAnnotation]; ok {
return componentType, nil
} else if _, ok = component.GetLabels()[componentlabels.ComponentTypeLabel]; ok {
klog.V(1).Info("No annotation assigned; retuning 'Not available' since labels are assigned. Annotations will be assigned when user pushes again.")
return NotAvailable, nil
}

return "", fmt.Errorf("%s component doesn't provide a type annotation; consider pushing the component again", component.GetName())
}

Expand Down Expand Up @@ -202,4 +203,5 @@ func isIgnorableError(err error) bool {
return true
}
return kerrors.IsNotFound(err) || kerrors.IsForbidden(err) || kerrors.IsUnauthorized(err)

}
11 changes: 4 additions & 7 deletions pkg/component/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type SecretMount struct {
// ComponentStatus is Status of components
type ComponentStatus struct {
Context string `json:"context,omitempty"`
State State `json:"state"`
State string `json:"state"`
LinkedServices []SecretMount `json:"linkedServices,omitempty"`
}

Expand All @@ -61,16 +61,13 @@ type CombinedComponentList struct {
OtherComponents []Component `json:"otherComponents"`
}

// State represents the component state
type State string

const (
// StateTypePushed means that Storage is present both locally and on cluster
StateTypePushed State = "Pushed"
StateTypePushed = "Pushed"
// StateTypeNotPushed means that Storage is only in local config, but not on the cluster
StateTypeNotPushed State = "Not Pushed"
StateTypeNotPushed = "Not Pushed"
// StateTypeUnknown means that odo cannot tell its state
StateTypeUnknown State = "Unknown"
StateTypeUnknown = "Unknown"
)

func newComponentWithType(componentName, componentType string) Component {
Expand Down
16 changes: 10 additions & 6 deletions pkg/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,26 @@ func (o *deployHandler) ApplyImage(img v1alpha2.Component) error {
return image.BuildPushSpecificImage(o.devfileObj, o.path, img, true)
}

// ApplyKubernetes applies inline Kubernetes YAML from the devfile.yaml file
func (o *deployHandler) ApplyKubernetes(kubernetes v1alpha2.Component) error {
// validate if the GVRs represented by Kubernetes inlined components are supported by the underlying cluster

// Validate if the GVRs represented by Kubernetes inlined components are supported by the underlying cluster
_, err := service.ValidateResourceExist(o.kubeClient, kubernetes, o.path)
if err != nil {
return err
}

// Get the most common labels that's applicable to all resources being deployed.
// Retrieve the component type from the devfile and also inject it into the list of labels
// Set the mode to DEPLOY. Regardless of what Kubernetes resource we are deploying.
labels := componentlabels.GetLabels(o.devfileObj.Data.GetMetadata().Name, o.appName, true)
componentType := component.GetComponentTypeFromDevfileMetadata(o.devfileObj.Data.GetMetadata())
labels[componentlabels.ComponentProjectTypeLabel] = componentType
labels[componentlabels.ComponentModeLabel] = componentlabels.ComponentDeployLabel
labels[componentlabels.ComponentModeLabel] = componentlabels.ComponentDeployName
klog.V(4).Infof("Injecting labels: %+v into k8s artifact", labels)

// Create the annotations
// Retrieve the component type from the devfile and also inject it into the list of annotations
annotations := make(map[string]string)
annotations[componentlabels.ComponentProjectTypeAnnotation] = component.GetComponentTypeFromDevfileMetadata(o.devfileObj.Data.GetMetadata())

// Get the Kubernetes component
u, err := service.GetK8sComponentAsUnstructured(kubernetes.Kubernetes, o.path, devfilefs.DefaultFs{})
if err != nil {
Expand All @@ -79,7 +83,7 @@ func (o *deployHandler) ApplyKubernetes(kubernetes v1alpha2.Component) error {

// Deploy the actual Kubernetes component and error out if there's an issue.
log.Infof("\nDeploying Kubernetes %s: %s", u.GetKind(), u.GetName())
isOperatorBackedService, err := service.PushKubernetesResource(o.kubeClient, u, labels)
isOperatorBackedService, err := service.PushKubernetesResource(o.kubeClient, u, labels, annotations)
if err != nil {
return errors.Wrap(err, "failed to create service(s) associated with the component")
}
Expand Down
Loading