Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

support for ingress resource fragment file generation #1396

Closed
Beennnn opened this issue Sep 26, 2018 · 8 comments
Closed

support for ingress resource fragment file generation #1396

Beennnn opened this issue Sep 26, 2018 · 8 comments
Assignees

Comments

@Beennnn
Copy link

Beennnn commented Sep 26, 2018

Description

I want to use Ingress in GCP as described here : https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer. To achieve this, I have to create an Ingress File.
I want to use fabric8-maven-plugin to do it but the plugin does not provide Ingress File generation.
Is it possible to support this feature for a future release ?

Info

The plugin documentation identifies a mechanism named "Resource Fragment" that can be used to generate Kubernetes files using enrichers but it does not support Ingress files.

In fact, the appendix contains contains ConfigMap, Secret, Service but no Ingress Kind:
https://maven.fabric8.io/#appendix-kind-mapping

When looking at the code, It confirms that the Ingress kind has not been taken into account.
I think it could be processed as done for the other kinds as the low level code provides all the base code in the package named io.fabric8.kubernetes.api.model.extensions:

import io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath;
import io.fabric8.kubernetes.api.model.extensions.HTTPIngressRuleValue;
import io.fabric8.kubernetes.api.model.extensions.Ingress;
import io.fabric8.kubernetes.api.model.extensions.IngressBackend;
import io.fabric8.kubernetes.api.model.extensions.IngressBuilder;
import io.fabric8.kubernetes.api.model.extensions.IngressFluent.MetadataNested;

Hacking

I successfully done it using a side effect with a development file based enricher: when processing the development builder, I create an ingress file and write it at the expected location.

		// As no IngressHandler is provided for the maven plugin, this operation
		// requires side-effect
		IngressBuilder ingressBuilder = new IngressBuilder();
		ingressBuilder.withApiVersion(API_VERSION);
		MavenProject project = getProject();
		String artifactId = project.getArtifactId();
		MetadataNested<IngressBuilder> metadata = ingressBuilder.editOrNewMetadata();
		Map<String, String> annotations = new HashMap<>();
		// manually call timestamp enricher
		TimestampEnricher.fillAnnotations(annotations);
		annotations.put(CLASS_KEY, CLASS_VALUE);
		annotations.put(REWRITE_TARGET_KEY, SUBPATH);
		metadata.withAnnotations(annotations);
		metadata.withName(artifactId).endMetadata();

		List<HTTPIngressPath> paths = new ArrayList<>();
		String path = SUBPATH + artifactId;
		IngressBackend backend = new IngressBackend(artifactId,
				new IntOrString(PORT));
		HTTPIngressPath ingressPath = new HTTPIngressPath(backend, path);
		paths.add(ingressPath);
		ingressBuilder.editOrNewSpec().addNewRule()
				.withHttp(new HTTPIngressRuleValue(paths)).endRule().endSpec();

		Ingress ingress = ingressBuilder.build();
		String name = KubernetesHelper.getName(ingress);
		// not processed by fabric8 until now
		// String itemFile = KubernetesResourceUtil.getNameWithSuffix(name,
		// ingress.getKind());
		String itemFile = name + "-" + SUFFIX;

		File basedir = project.getBasedir();
		File f8TargetDir = new File(basedir, getf8OutputDir());
		File targetDir = new File(f8TargetDir,
				ResourceClassifier.KUBERNETES.getValue());
		targetDir.mkdirs();
		File targetWithoutExtension = new File(targetDir, itemFile);
		try {
			write(ingress, targetWithoutExtension);
		}
		catch (IOException e) {
			throw new RuntimeException("unable to write ingress file", e);

		}

Then I post process the main file "kubernetes.yml" reading it, adding the ingress file, and rewriting at a later stage in the maven process.

	private static void concatToAllFile(File targetWithoutExtension,
			File allTargetWithoutExtension) throws IOException {
		File target = RESOURCE_FILE_TYPE.addExtension(targetWithoutExtension);

		if (target.exists()) {
			File manifest = RESOURCE_FILE_TYPE.addExtension(allTargetWithoutExtension);
			Set<HasMetadata> otherResources = KubernetesResourceUtil
					.loadResources(manifest);
			// ingress type not supported, use lower level code
			// HasMetadata resource = KubernetesResourceUtil.getResource(
			// KubernetesResourceUtil.DEFAULT_RESOURCE_VERSIONING, target, name);
			ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
			TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() {
			};
			Map<String, Object> fragment = mapper.readValue(target, typeRef);
			HasMetadata resource = mapper.convertValue(fragment, HasMetadata.class);

			KubernetesListBuilder builder = new KubernetesListBuilder();
			for (HasMetadata otherResource : otherResources) {
				builder.addToItems(otherResource);
			}
			builder.addToItems(resource);
			KubernetesList kubernetesList = builder.build();

			// create KubernetesList then rewrite all
			// append to complete file
			logger.info("append {} file content to {}", target, manifest);
			KubernetesResourceUtil.writeResource(kubernetesList,
					allTargetWithoutExtension,
					ResourceFileType.yaml);
			KubernetesResourceUtil.writeResource(kubernetesList,
					allTargetWithoutExtension,
					ResourceFileType.json);

		}
		else {
			logger.info("skip missing file {}", target);
		}
	}

I could be made simpler...

It would be much better to make it part of the plugin and share it with the community. Do you think it could be possible to integrate it into the plugin ?

ExposeController

Note: I also notice the fmp-service enricher supports expose controller but I did not successfully migrate to it. I think using the expose controller could be a solution for some cases but not as flexible as resource fragments, and so the plugin should also provide Ingress file fragments without the need for exposecontroller. I also created a ticket there: jenkins-x/exposecontroller#148

Thanks,
Ben.

@stale
Copy link

stale bot commented Dec 25, 2018

This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions!

@stale stale bot added the status/stale Issue/PR considered to be stale label Dec 25, 2018
@rohanKanojia
Copy link
Member

Hm, sounds like a genuine issue to me. I tried using an ingress resource fragment and was able to create ingress resource. We can provide an option in xml-config too in order to generate yaml; thoughts @rhuss @lordofthejars @dev-gaur ???

@rohanKanojia rohanKanojia removed the status/stale Issue/PR considered to be stale label Dec 31, 2018
@wadeholler
Copy link

@rohanKanojia - could you please share your yaml ? I am struggling to see how to create the resource fragment

@rohanKanojia
Copy link
Member

@wadeholler : Sorry for the delay, I just placed an ingress.yml provided in Kubernetes documentation in the fragments directory(src/main/fabric8) :

~/work/repos/fabric8-maven-plugin/samples/yaml-only : $ mvn fabric8:resource 
[INFO] Scanning for projects...
[INFO] 
[INFO] -----------< io.fabric8:fabric8-maven-sample-raw-with-yaml >------------
[INFO] Building Fabric8 Maven :: Sample :: Yaml 4.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- fabric8-maven-plugin:4.0-SNAPSHOT:resource (default-cli) @ fabric8-maven-sample-raw-with-yaml ---
[INFO] F8: Running in Kubernetes mode
[INFO] F8: using resource templates from /home/Rohaan/work/repos/fabric8-maven-plugin/samples/yaml-only/src/main/fabric8
[INFO] F8: validating /home/Rohaan/work/repos/fabric8-maven-plugin/samples/yaml-only/target/classes/META-INF/fabric8/openshift/password-secret.yml resource
[INFO] F8: validating /home/Rohaan/work/repos/fabric8-maven-plugin/samples/yaml-only/target/classes/META-INF/fabric8/openshift/test-ingress.yml resource
[INFO] F8: validating /home/Rohaan/work/repos/fabric8-maven-plugin/samples/yaml-only/target/classes/META-INF/fabric8/kubernetes/password-secret.yml resource
[INFO] F8: validating /home/Rohaan/work/repos/fabric8-maven-plugin/samples/yaml-only/target/classes/META-INF/fabric8/kubernetes/test-ingress.yml resource
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: २.५३१ s
[INFO] Finished at: २०१९-०१-१०T१७:१६:००+05:30
[INFO] ------------------------------------------------------------------------
~/work/repos/fabric8-maven-plugin/samples/yaml-only : $ mvn fabric8:apply
[INFO] Scanning for projects...
[INFO] 
[INFO] -----------< io.fabric8:fabric8-maven-sample-raw-with-yaml >------------
[INFO] Building Fabric8 Maven :: Sample :: Yaml 4.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- fabric8-maven-plugin:4.0-SNAPSHOT:apply (default-cli) @ fabric8-maven-sample-raw-with-yaml ---
[INFO] F8: Using Kubernetes at https://192.168.42.34:8443/ in namespace default with manifest /home/Rohaan/work/repos/fabric8-maven-plugin/samples/yaml-only/target/classes/META-INF/fabric8/kubernetes.yml 
[INFO] F8: Using namespace: default
[INFO] F8: Using namespace: default
[INFO] F8: Updating a Secret from kubernetes.yml
[INFO] F8: Updated Secret:target/fabric8/applyJson/default/secret-password-1.json
[WARNING] The client is using resource type 'ingresses' with unstable version 'v1beta1'
[INFO] F8: Updating Ingress from kubernetes.yml
[INFO] F8: Updated Ingress: target/fabric8/applyJson/default/ingress-test-ingress-1.json
[INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: २.०५६ s
[INFO] Finished at: २०१९-०१-१०T१७:१६:४८+05:30
[INFO] ------------------------------------------------------------------------
~/work/repos/fabric8-maven-plugin/samples/yaml-only : $ kubectl get ingress
NAME           HOSTS   ADDRESS   PORTS   AGE
test-ingress   *                 80      4m6s
~/work/repos/fabric8-maven-plugin/samples/yaml-only : $ 

@stale
Copy link

stale bot commented Apr 10, 2019

This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions!

@stale stale bot added the status/stale Issue/PR considered to be stale label Apr 10, 2019
@rohanKanojia
Copy link
Member

@wadeholler : Polite ping, Could you please find time to check if it's working for you?

@stale stale bot removed the status/stale Issue/PR considered to be stale label Apr 11, 2019
@devang-gaur
Copy link
Contributor

@rohanKanojia Even though the ingress yaml seems to generate an ingress resource, we need a better solution for ingress here..

Currently, ingress (and route for openshift ) is created by the ApplyMojo if set the

createExternalUrls property in XML as true.

Although, We need to make things better here.. by adding an Enricher for Ingress similar to Route :
https://github.com/fabric8io/fabric8-maven-plugin/blob/b3c6060b21fabdbe29eb03cc23cdf08a2353ace2/enricher/standard/src/main/java/io/fabric8/maven/enricher/standard/openshift/RouteEnricher.java

@devang-gaur devang-gaur self-assigned this Jul 17, 2019
@devang-gaur
Copy link
Contributor

@Beennnn I believe #1631 have resolved your case. Closing this issue. Feel free to re-open if you want any more work done for ingress.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants