diff --git a/pkg/util/sparkapplication.go b/pkg/util/sparkapplication.go index a0aadd93f..65bdb2692 100644 --- a/pkg/util/sparkapplication.go +++ b/pkg/util/sparkapplication.go @@ -17,6 +17,7 @@ limitations under the License. package util import ( + "crypto/md5" "fmt" "reflect" "strings" @@ -155,12 +156,25 @@ func GetExecutorLocalVolumeMounts(app *v1beta2.SparkApplication) []corev1.Volume return volumeMounts } +func generateName(name, suffix string) string { + // Some resource names are used as DNS labels, so must be 63 characters or shorter + preferredName := fmt.Sprintf("%s-%s", name, suffix) + if len(preferredName) <= 63 { + return preferredName + } + + // Truncate the name and append a hash to ensure uniqueness while staying below the limit + maxNameLength := 63 - len(suffix) - 10 // 8 for the hash, 2 for the dash + hash := fmt.Sprintf("%x", md5.Sum([]byte(preferredName))) + return fmt.Sprintf("%s-%s-%s", name[:maxNameLength], hash[:8], suffix) +} + func GetDefaultUIServiceName(app *v1beta2.SparkApplication) string { - return fmt.Sprintf("%s-ui-svc", app.Name) + return generateName(app.Name, "ui-svc") } func GetDefaultUIIngressName(app *v1beta2.SparkApplication) string { - return fmt.Sprintf("%s-ui-ingress", app.Name) + return generateName(app.Name, "ui-ingress") } func GetResourceLabels(app *v1beta2.SparkApplication) map[string]string { diff --git a/pkg/util/sparkapplication_test.go b/pkg/util/sparkapplication_test.go index 7f0ab4a46..3aaa57e82 100644 --- a/pkg/util/sparkapplication_test.go +++ b/pkg/util/sparkapplication_test.go @@ -284,6 +284,20 @@ var _ = Describe("GetDefaultUIServiceName", func() { It("Should return the default UI service name", func() { Expect(util.GetDefaultUIServiceName(app)).To(Equal("test-app-ui-svc")) }) + + appWithLongName := &v1beta2.SparkApplication{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-app-with-a-long-name-that-would-be-over-63-characters", + Namespace: "test-namespace", + }, + } + + It("Should truncate the app name so the service name is below 63 characters", func() { + serviceName := util.GetDefaultUIServiceName(appWithLongName) + Expect(len(serviceName)).To(BeNumerically("<=", 63)) + Expect(serviceName).To(HavePrefix(appWithLongName.Name[:47])) + Expect(serviceName).To(HaveSuffix("-ui-svc")) + }) }) var _ = Describe("GetDefaultUIIngressName", func() { @@ -297,6 +311,20 @@ var _ = Describe("GetDefaultUIIngressName", func() { It("Should return the default UI ingress name", func() { Expect(util.GetDefaultUIIngressName(app)).To(Equal("test-app-ui-ingress")) }) + + appWithLongName := &v1beta2.SparkApplication{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-app-with-a-long-name-that-would-be-over-63-characters", + Namespace: "test-namespace", + }, + } + + It("Should truncate the app name so the ingress name is below 63 characters", func() { + serviceName := util.GetDefaultUIIngressName(appWithLongName) + Expect(len(serviceName)).To(BeNumerically("<=", 63)) + Expect(serviceName).To(HavePrefix(appWithLongName.Name[:42])) + Expect(serviceName).To(HaveSuffix("-ui-ingress")) + }) }) var _ = Describe("IsDriverTerminated", func() {