Skip to content

Commit

Permalink
feat(tasks): introduce SMB protocol VFS (Samba for eg.)
Browse files Browse the repository at this point in the history
closes #23
  • Loading branch information
tchiotludo authored and brian-mulier-p committed Dec 29, 2023
1 parent 2a19a93 commit 3f34eb1
Show file tree
Hide file tree
Showing 30 changed files with 1,078 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ out/
.attach*
src/test/resources/application-test.yml
id_rsa*
shares/
11 changes: 10 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ configurations.all {
}
}

repositories {
maven { url 'https://jitpack.io' }
}

dependencies {
// lombok
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
Expand All @@ -54,10 +58,15 @@ dependencies {
compileOnly group: "io.kestra", name: "core", version: kestraVersion

// libs
api group: 'org.apache.commons', name: 'commons-vfs2', version: '2.9.0'
// use a custom build to have sandbox project
// api group: 'org.apache.commons', name: 'commons-vfs2', version: '2.9.0'
api group: 'com.github.kestra-io.commons-vfs', name: 'commons-vfs2', version: '58e484e5c14907ea8e5a4b02a66f8aa2830ca7c6'
api group: 'com.github.new-proimage', name: 'vfs-jcifs-smb', version: '0.9.3'
api group: 'com.jcraft', name: 'jsch', version: '0.1.55'
api 'commons-net:commons-net:3.9.0'
api group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.36'
api group: 'org.codelibs', name: 'jcifs', version: '2.1.37'

}


Expand Down
23 changes: 23 additions & 0 deletions docker-compose-ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
version: "3.6"

volumes:
samba-data:
driver: local
another-samba-data:
driver: local

services:
sftp:
image: atmoz/sftp
Expand Down Expand Up @@ -40,3 +46,20 @@ services:
SSH_ENABLE_PASSWORD_AUTH: "true"
volumes:
- ${PWD}/src/test/resources/ssh/:/etc/entrypoint.d/

samba:
image: elswork/samba
container_name: samba
ports:
- "139:139"
- "445:445"
volumes:
- samba-data:/share/data/to_share
- another-samba-data:/share/data/second_share
entrypoint: /bin/bash -c
command: >
'sed -i "\$$i chown -R 1000:1000 /share/data" /entrypoint.sh &&
/entrypoint.sh
-u "1000:1000:alice:alice:alipass"
-s "upload:/share/data/to_share:rw:alice"
-s "another_upload:/share/data/second_share:rw:alice"'
48 changes: 48 additions & 0 deletions src/main/java/io/kestra/plugin/fs/smb/Delete.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.kestra.plugin.fs.smb;

import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.Example;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.vfs2.FileSystemOptions;

import java.io.IOException;

@SuperBuilder(toBuilder = true)
@ToString
@EqualsAndHashCode
@Getter
@NoArgsConstructor
@Schema(
title = "Delete a file from a SMB (Samba for eg.) server."
)
@Plugin(
examples = {
@Example(
code = {
"host: localhost",
"port: 445",
"username: foo",
"password: pass",
"uri: \"/my_share/dir1/file.txt\"",
}
)
}
)
public class Delete extends io.kestra.plugin.fs.vfs.Delete implements SmbInterface {
@Builder.Default
protected String port = "445";

@Override
protected FileSystemOptions fsOptions(RunContext runContext) throws IllegalVariableEvaluationException, IOException {
return SmbService.fsOptions(runContext, this);
}

@Override
protected String scheme() {
return "smb";
}
}
48 changes: 48 additions & 0 deletions src/main/java/io/kestra/plugin/fs/smb/Download.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.kestra.plugin.fs.smb;

import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.Example;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.vfs2.FileSystemOptions;

import java.io.IOException;

@SuperBuilder(toBuilder = true)
@ToString
@EqualsAndHashCode
@Getter
@NoArgsConstructor
@Schema(
title = "Download file from SMB (Samba for eg.) server"
)
@Plugin(
examples = {
@Example(
code = {
"host: localhost",
"port: 445",
"username: foo",
"password: pass",
"from: \"/my_share/file.txt\"",
}
)
}
)
public class Download extends io.kestra.plugin.fs.vfs.Download implements SmbInterface {
@Builder.Default
protected String port = "445";

@Override
protected FileSystemOptions fsOptions(RunContext runContext) throws IllegalVariableEvaluationException, IOException {
return SmbService.fsOptions(runContext, this);
}

@Override
protected String scheme() {
return "smb";
}
}
52 changes: 52 additions & 0 deletions src/main/java/io/kestra/plugin/fs/smb/Downloads.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.kestra.plugin.fs.smb;

import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.Example;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.vfs2.FileSystemOptions;

import java.io.IOException;

@SuperBuilder(toBuilder = true)
@ToString
@EqualsAndHashCode
@Getter
@NoArgsConstructor
@Schema(
title = "Download multiple files from a SMB (Samba for eg.) server"
)
@Plugin(
examples = {
@Example(
title = "Download files from `my_share` and move them to an `archive_share`",
code = {
"host: localhost",
"port: 445",
"username: foo",
"password: pass",
"from: \"/my_share/\"",
"interval: PT10S",
"action: MOVE",
"moveDirectory: \"/archive_share/\"",
}
)
}
)
public class Downloads extends io.kestra.plugin.fs.vfs.Downloads implements SmbInterface {
@Builder.Default
protected String port = "445";

@Override
protected FileSystemOptions fsOptions(RunContext runContext) throws IllegalVariableEvaluationException, IOException {
return SmbService.fsOptions(runContext, this);
}

@Override
protected String scheme() {
return "smb";
}
}
49 changes: 49 additions & 0 deletions src/main/java/io/kestra/plugin/fs/smb/List.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.kestra.plugin.fs.smb;

import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.Example;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.vfs2.FileSystemOptions;

import java.io.IOException;

@SuperBuilder
@ToString
@EqualsAndHashCode
@Getter
@NoArgsConstructor
@Schema(
title = "List files from a SMB (Samba for eg.) server directory"
)
@Plugin(
examples = {
@Example(
code = {
"host: localhost",
"port: 445",
"username: foo",
"password: pass",
"from: \"/my_share/dir1/\"",
"regExp: \".*\\/dir1\\/.*\\.(yaml|yml)\"",
}
)
}
)
public class List extends io.kestra.plugin.fs.vfs.List implements SmbInterface {
@Builder.Default
protected String port = "445";

@Override
protected FileSystemOptions fsOptions(RunContext runContext) throws IllegalVariableEvaluationException, IOException {
return SmbService.fsOptions(runContext, this);
}

@Override
protected String scheme() {
return "smb";
}
}
50 changes: 50 additions & 0 deletions src/main/java/io/kestra/plugin/fs/smb/Move.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.kestra.plugin.fs.smb;

import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.Example;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.vfs2.FileSystemOptions;

import java.io.IOException;

@SuperBuilder
@ToString
@EqualsAndHashCode
@Getter
@NoArgsConstructor
@Schema(
title = "Move a file to a different share / folder on a SMB (Samba for eg.) server.",
description = "If the destination directory doesn't exist, it will be created"
)
@Plugin(
examples = {
@Example(
code = {
"host: localhost",
"port: 445",
"username: foo",
"password: pass",
"from: \"/my_share/dir1/file.txt\"",
"to: \"/my_share/dir2/file.txt\"",
}
)
}
)
public class Move extends io.kestra.plugin.fs.vfs.Move implements SmbInterface {
@Builder.Default
protected String port = "445";

@Override
protected FileSystemOptions fsOptions(RunContext runContext) throws IllegalVariableEvaluationException, IOException {
return SmbService.fsOptions(runContext, this);
}

@Override
protected String scheme() {
return "smb";
}
}
7 changes: 7 additions & 0 deletions src/main/java/io/kestra/plugin/fs/smb/SmbInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.kestra.plugin.fs.smb;

import io.kestra.plugin.fs.vfs.AbstractVfsInterface;

public interface SmbInterface extends AbstractVfsInterface {

}
21 changes: 21 additions & 0 deletions src/main/java/io/kestra/plugin/fs/smb/SmbService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.kestra.plugin.fs.smb;

import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.RunContext;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.auth.StaticUserAuthenticator;
import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;

import java.io.IOException;

public abstract class SmbService {
public static FileSystemOptions fsOptions(RunContext runContext, SmbInterface smbInterface) throws IOException, IllegalVariableEvaluationException {
FileSystemOptions opts = new FileSystemOptions();
DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(
opts,
new StaticUserAuthenticator("", smbInterface.getUsername(), smbInterface.getPassword())
);

return opts;
}
}
Loading

0 comments on commit 3f34eb1

Please sign in to comment.