Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
24 changes: 12 additions & 12 deletions .github/workflows/python-tester.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ jobs:
- name: Poetry installation
run: |
poetry install
# Run the 'Try it yourself'
- uses: Getdeck/getdeck-action@main
name: Create Infrastructure from Deckfile
with:
deck-file-path: https://github.com/gefyrahq/gefyra-demos.git
timeout: "180"
- name: Remove cluster using getdeck
run: |
poetry run coverage run -a -m getdeck remove deck.gefyra.test.yaml --name oauth2-demo
- name: Install k3d
shell: bash
run: "curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash"
- name: Create a cluster using getdeck
run: |
poetry run coverage run -a -m getdeck get deck.gefyra.test.yaml --name oauth2-demo
- name: Stop cluster
poetry run coverage run -a -m getdeck get --name oauth2-demo --wait --timeout 180 https://github.com/gefyrahq/gefyra-demos.git
- name: Stop the cluster
run: |
poetry run coverage run -a -m getdeck stop https://github.com/gefyrahq/gefyra-demos.git
- name: Start the cluster again
run: |
poetry run coverage run -a -m getdeck get --name oauth2-demo https://github.com/gefyrahq/gefyra-demos.git
- name: Remove the cluster
run: |
poetry run coverage run -a -m getdeck stop deck.gefyra.test.yaml
poetry run coverage run -a -m getdeck remove --cluster https://github.com/gefyrahq/gefyra-demos.git
- name: Show coverage report
run: |
poetry run coverage report
Expand Down
5 changes: 5 additions & 0 deletions getdeck/deckfile/deckfile_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@


class Deckfile_1_0(Deckfile, BaseModel):
# meta
file_path: str
file_name: str

# content
version: Optional[str]
cluster: DeckfileCluster = None
decks: List[DeckfileDeck]
Expand Down
6 changes: 5 additions & 1 deletion getdeck/deckfile/selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ def get(self, path_deckfile: str = None) -> Union[Deckfile, Deckfile_1_0, None]:
else:
raise DeckfileVersionError("Version in Deckfile is missing")
logger.debug("The raw Deckfile data: " + str(data))
return deckfile_class(**data)

file_path = os.path.dirname(path_deckfile)
file_name = os.path.basename(path_deckfile)
deckfile = deckfile_class(file_path=file_path, file_name=file_name, **data)
return deckfile


deckfile_selector = DeckfileSelector(
Expand Down
83 changes: 83 additions & 0 deletions getdeck/sources/fetcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import logging
from operator import methodcaller
from typing import List, Union

from getdeck.configuration import ClientConfiguration
from getdeck.deckfile.file import (
DeckfileFileSource,
DeckfileKustomizeSource,
DeckfileHelmSource,
)
from getdeck.sources.types import K8sSourceFile
from getdeck.utils import sniff_protocol

logger = logging.getLogger("deck")


class FetcherError(Exception):
pass


class Fetcher:
def __init__(
self,
path: str,
source: Union[DeckfileFileSource, DeckfileKustomizeSource, DeckfileHelmSource],
config: ClientConfiguration,
namespace: str,
):
self.path = path
self.source = source
self.config = config
self.namespace = namespace

@property
def not_supported_message(self):
return "Could not fetch source"

def fetch(self, **kwargs) -> List[K8sSourceFile]:
handler = methodcaller(f"fetch_{self.type}", **kwargs)
try:
return handler(self)
except NotImplementedError:
logger.warning(self.not_supported_message)
return []

@property
def type(self) -> str:
if getattr(self.source, "content", None) is not None:
return "content"
protocol = sniff_protocol(self.source.ref)
return protocol

def fetch_git(self, **kwargs):
raise NotImplementedError

def fetch_http(self, **kwargs):
raise NotImplementedError

def fetch_https(self, **kwargs):
raise NotImplementedError

def fetch_local(self, **kwargs):
raise NotImplementedError

def fetch_content(self, **kwargs):
raise NotImplementedError


class FetcherContext:
def __init__(self, strategy: Fetcher) -> None:
self._strategy = strategy

@property
def strategy(self) -> Fetcher:
return self._strategy

@strategy.setter
def strategy(self, strategy: Fetcher) -> None:
self._strategy = strategy

def fetch_source_files(self) -> List[K8sSourceFile]:
source_files = self._strategy.fetch()
return source_files
101 changes: 26 additions & 75 deletions getdeck/sources/file.py
Original file line number Diff line number Diff line change
@@ -1,101 +1,44 @@
import logging
from operator import methodcaller
import os
from pathlib import PurePath
import tempfile
from typing import List, Union
from typing import List

import requests
import yaml

from getdeck.configuration import ClientConfiguration
from getdeck.deckfile.file import (
DeckfileFileSource,
DeckfileKustomizeSource,
DeckfileHelmSource,
)
from getdeck.sources.fetcher import Fetcher, FetcherError
from getdeck.sources.types import K8sSourceFile
from getdeck.utils import sniff_protocol
from git import Repo

logger = logging.getLogger("deck")


class FetcherError(Exception):
pass


class Fetcher:
def __init__(
self,
source: Union[DeckfileFileSource, DeckfileKustomizeSource, DeckfileHelmSource],
config: ClientConfiguration,
namespace: str,
):
self.source = source
self.config = config
self.namespace = namespace

@property
def not_supported_message(self):
return "Could not fetch source"

def fetch(self, **kwargs) -> List[K8sSourceFile]:
handler = methodcaller(f"fetch_{self.type}", **kwargs)
try:
return handler(self)
except NotImplementedError:
logger.warning(self.not_supported_message)
return []

@property
def type(self) -> str:
if getattr(self.source, "content", None) is not None:
return "content"
protocol = sniff_protocol(self.source.ref)
return protocol

def fetch_git(self, **kwargs):
raise NotImplementedError

def fetch_http(self, **kwargs):
raise NotImplementedError

def fetch_https(self, **kwargs):
raise NotImplementedError

def fetch_local(self, **kwargs):
raise NotImplementedError

def fetch_content(self, **kwargs):
raise NotImplementedError


class FileFetcher(Fetcher):
@property
def not_supported_message(self):
return f"Protocol {self.type} not supported for {type(self.source).__name__}"

@staticmethod
def _parse_source_file(ref: str) -> List[K8sSourceFile]:
def _parse_source_file(self, ref: str) -> List[K8sSourceFile]:
with open(ref, "r") as input_file:
docs = yaml.load_all(input_file.read(), Loader=yaml.FullLoader)

k8s_workload_files = []
for doc in docs:
if doc:
k8s_workload_files.append(K8sSourceFile(name=ref, content=doc))
k8s_workload_files.append(
K8sSourceFile(name=ref, content=doc, namespace=self.namespace)
)
return k8s_workload_files

@staticmethod
def _parse_source_files(refs: List[str]) -> List[K8sSourceFile]:
def _parse_source_files(self, refs: List[str]) -> List[K8sSourceFile]:
k8s_workload_files = []
for ref in refs:
workloads = FileFetcher._parse_source_file(ref=ref)
workloads = self._parse_source_file(ref=ref)
k8s_workload_files += workloads
return k8s_workload_files

@staticmethod
def _parse_source_directory(ref: str) -> List[K8sSourceFile]:
def _parse_source_directory(self, ref: str) -> List[K8sSourceFile]:
refs = []

if not os.path.isdir(ref):
Expand All @@ -109,19 +52,23 @@ def _parse_source_directory(ref: str) -> List[K8sSourceFile]:
refs.append(os.path.join(ref, file))

# parse workloads
k8s_workload_files = FileFetcher._parse_source_files(refs=refs)
k8s_workload_files = self._parse_source_files(refs=refs)
return k8s_workload_files

@staticmethod
def _parse_source(ref: str) -> List[K8sSourceFile]:
def _parse_source(self, ref: str) -> List[K8sSourceFile]:
if os.path.isdir(ref):
k8s_workload_files = FileFetcher._parse_source_directory(ref=ref)
k8s_workload_files = self._parse_source_directory(
ref=ref,
)
else:
k8s_workload_files = FileFetcher._parse_source_file(ref=ref)
k8s_workload_files = self._parse_source_file(ref=ref)
return k8s_workload_files

def fetch_content(self, **kwargs) -> List[K8sSourceFile]:
return [K8sSourceFile(name="Deckfile", content=self.source.content)]
source_file = K8sSourceFile(
name="Deckfile", content=self.source.content, namespace=self.namespace
)
return [source_file]

def fetch_http(self, **kwargs) -> List[K8sSourceFile]:
k8s_workload_files = []
Expand All @@ -134,7 +81,9 @@ def fetch_http(self, **kwargs) -> List[K8sSourceFile]:
for doc in docs:
if doc:
k8s_workload_files.append(
K8sSourceFile(name=self.source.ref, content=doc)
K8sSourceFile(
name=self.source.ref, content=doc, namespace=self.namespace
)
)
return k8s_workload_files
except Exception as e:
Expand All @@ -147,7 +96,9 @@ def fetch_https(self, **kwargs):
def fetch_local(self, **kwargs):
try:
logger.debug(f"Reading file {self.source.ref}")
k8s_workload_files = self._parse_source(ref=self.source.ref)
ref = str(PurePath(os.path.join(self.path, self.source.ref)))

k8s_workload_files = self._parse_source(ref=ref)
return k8s_workload_files
except Exception as e:
logger.error(f"Error loading file from http {e}")
Expand Down
21 changes: 21 additions & 0 deletions getdeck/sources/selector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from typing import Union
from getdeck.deckfile.file import (
DeckfileFileSource,
DeckfileHelmSource,
DeckfileKustomizeSource,
)
from getdeck.sources.fetcher import Fetcher
from getdeck.sources.file import FileFetcher
from getdeck.sources.helm import HelmFetcher
from getdeck.sources.kustomize import KustomizeFetcher


def select_fetcher_strategy(
source: Union[DeckfileFileSource, DeckfileHelmSource, DeckfileKustomizeSource]
) -> Fetcher | None:
fetcher_strategy = {
DeckfileFileSource: FileFetcher,
DeckfileHelmSource: HelmFetcher,
DeckfileKustomizeSource: KustomizeFetcher,
}.get(type(source), None)
return fetcher_strategy
Loading