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

converter for istio in-cluster operator config to sail operator config #616

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

ctartici
Copy link

@ctartici ctartici commented Feb 5, 2025

What type of PR is this?

  • Enhancement / New Feature
  • Bug Fix
  • Refactor
  • Optimization
  • Test
  • Documentation Update

What this PR does / why we need it:

Which issue(s) this PR fixes:

Fixes #

Related Issue/PR #

Additional information:

@istio-testing
Copy link
Collaborator

Hi @ctartici. Thanks for your PR.

I'm waiting for a istio-ecosystem or istio member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@fjglira
Copy link
Contributor

fjglira commented Feb 5, 2025

/ok-to-test

Copy link
Contributor

@fjglira fjglira left a comment

Choose a reason for hiding this comment

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

LGTM adding this we will give to the users the possibility to easily convert their configuration to sail operator Istio resource. Also, this is needed to execute the upstream Istio integration test later against Sail Operator installed control plane increasing the testing coverage. Adding a hold in case someone else want to review it

docs/README.md Outdated Show resolved Hide resolved
cp "$ISTIO_CONFIG_FILE" "$SAIL_CONFIG_FILE"

function add_mandatory_fields(){
sail_api=".apiVersion=\"sailoperator.io/v1alpha1\""
Copy link
Contributor

Choose a reason for hiding this comment

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

Sail Operator APIs are now v1

Suggested change
sail_api=".apiVersion=\"sailoperator.io/v1alpha1\""
sail_api=".apiVersion=\"sailoperator.io/v1\""

Copy link
Author

Choose a reason for hiding this comment

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

Done

@ctartici
Copy link
Author

ctartici commented Feb 7, 2025

/retest

@ctartici
Copy link
Author

/retest

docs/README.md Outdated
Comment on lines 313 to 315
export ISTIO_VERSION=v1.24.0
export ISTIO_NAMESPACE=istio-system
./tools/configuration-converter.sh <ISTIO_OPERATOR_CONFIG_YAML_WITH_PATH>
Copy link
Contributor

Choose a reason for hiding this comment

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

BTW, why use environment variables if the version and namespace are required? Why not pass them as arguments to the script?

Copy link
Author

Choose a reason for hiding this comment

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

This script will be downloaded and executed from integ-suite-ocp.sh We are planning to run downstream integration tests with it and in there these env variables are already defined. Also since integ-suite-ocp.sh already gets many arguments(tests suite to run, tests to skip) It would have been so confusing.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, but can't integ-suite-ocp.sh simply pass the environment variables as arguments to the converter? It's weird that a shell script takes one required input as an argument, and other required inputs as an env var.

Also, won't users try to use this script as well? To convert examples from the upstream docs, for example.

Copy link
Author

Choose a reason for hiding this comment

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

Yes I can modify integ-suite-ocp.sh to pass arguments to the converter. You are right it will be cleaner for the users using directly the converter. Will update the readme also according to this.

pkg/converter/converter_test.go Outdated Show resolved Hide resolved
pkg/converter/converter_test.go Outdated Show resolved Hide resolved
| del(.spec.tag)
| del(.spec.values.gateways)
' "$SAIL_CONFIG_FILE" > tmp.yaml
mv tmp.yaml $SAIL_CONFIG_FILE
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can use yq eval -i to update the original file directly; no need to write to a temporary file.

Copy link
Author

@ctartici ctartici Feb 11, 2025

Choose a reason for hiding this comment

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

yq -i is not able to be executed for the files in root directories like /tmp if installed with snap. Since /tmp is default directory for integration tests it is necessary to create a temporary file.

Copy link
Author

Choose a reason for hiding this comment

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

implemented a workaround since yq -i is not working on root directories

Copy link
Author

Choose a reason for hiding this comment

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

Done now using yq -i

Comment on lines 61 to 64
cat $SAIL_CONFIG_FILE | yq '(.spec.values.[].env.[] | select(. == true)) |= "true"' > tmp.yaml
mv tmp.yaml $SAIL_CONFIG_FILE
cat $SAIL_CONFIG_FILE | yq '(.spec.values.[].env.[] | select(. == false)) |= "false"' | sed '/env: \[\]/d' > tmp.yaml
mv tmp.yaml $SAIL_CONFIG_FILE
Copy link
Contributor

Choose a reason for hiding this comment

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

This, too, can probably be done with a single yq command.

Copy link
Author

Choose a reason for hiding this comment

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

Done

Comment on lines 76 to 77
cat $SAIL_CONFIG_FILE | yq 'del(.spec.components.[] | keys[] | select(. != "enabled"))' | yq '.spec.values *= .spec.components | del (.spec.components)' > tmp.yaml
mv tmp.yaml $SAIL_CONFIG_FILE
Copy link
Contributor

Choose a reason for hiding this comment

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

Also could be a single yq command (+ no need for a temporary file).

Copy link
Author

Choose a reason for hiding this comment

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

implemented a workaround since yq -i is not working on root directories

Copy link
Author

Choose a reason for hiding this comment

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

Done now using yq -i

Comment on lines 80 to 81
cat $SAIL_CONFIG_FILE | yq 'del (.spec.components)' > tmp.yaml
mv tmp.yaml $SAIL_CONFIG_FILE
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
cat $SAIL_CONFIG_FILE | yq 'del (.spec.components)' > tmp.yaml
mv tmp.yaml $SAIL_CONFIG_FILE
yq -i 'del (.spec.components)' "$SAIL_CONFIG_FILE"

Copy link
Author

Choose a reason for hiding this comment

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

Done

@ctartici ctartici force-pushed the main branch 7 times, most recently from e8b4436 to e4f4b4a Compare February 11, 2025 23:17
cp "$WORKDIR"/"$ISTIO_CONFIG_FILE" "$SAIL_CONFIG_FILE" || exit 1

function add_mandatory_fields(){
yq -i eval ".apiVersion = \"sailoperator.io/v1\"
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would add a check for the yq binary installed.
Otherwise, the command will fail without specifying a reason.

Copy link
Author

Choose a reason for hiding this comment

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

It will fail with yq command not found. You think I need to catch command not found and inform user with better error message?

Copy link
Collaborator

Choose a reason for hiding this comment

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

You could add the following function.
It will check for the yq command available.
And if missing, will download it and use.

function verify_yq() {
    if ! command -v yq &> /dev/null; then
        if [[ "${OS}" == "darwin" ]]; then
            ERROR "Perform 'brew install yq' and try again."
        elif [[ "${OS}" == "linux" ]]; then
            WARNING "Missing yq command. Installing..."
            mkdir -p "$HOME"/.local/bin
            wget -qO- https://github.com/mikefarah/yq/releases/download/v4.16.2/yq_linux_amd64 \
                -O "$HOME"/.local/bin/yq && chmod +x "$HOME"/.local/bin/yq
            
            # Add local BIN dir to PATH
            [[ ":$PATH:" = *":$HOME/.local/bin:"* ]] || export PATH="$HOME/.local/bin:$PATH"
        fi
        INFO "The yq command installed"
    fi
    INFO "The yq command is found"
}

Or just check and explicitly tell the user what is missing.

Copy link
Author

Choose a reason for hiding this comment

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

Done. added an error message for yq installation

# Note that if there is an entry except spec.components.<component>.enabled: true/false converter will delete them and warn user
function validate_spec_components(){
yq -i 'del(.spec.components.[] | keys[] | select(. != "enabled")) | .spec.values *= .spec.components | del (.spec.components)' $SAIL_CONFIG_FILE
echo "Converter can only be used values with spec.components.<component>.enabled: true/false. Please see https://github.com/istio-ecosystem/sail-operator/tree/main/docs#components-field"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Converted can only use values with....

Copy link
Author

Choose a reason for hiding this comment

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

Done. changed the sentence

docs/README.md Outdated
Comment on lines 312 to 314
ISTIO_OPERATOR_CONFIG_YAML_WITH_PATH: Path to the Istio operator configuration YAML file.
ISTIO_NAMESPACE: The Kubernetes namespace for the Istio deployment.
ISTIO_VERSION: The version of Istio to be used.
Copy link
Contributor

Choose a reason for hiding this comment

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

Since the ISTIO_OPERATOR_CONFIG_YAML_WITH_PATH, ISTIO_NAMESPACE, and ISTIO_VERSION aren't shown in the example, you can probably just remove them here and just explain the arguments (in the correct order):

Suggested change
ISTIO_OPERATOR_CONFIG_YAML_WITH_PATH: Path to the Istio operator configuration YAML file.
ISTIO_NAMESPACE: The Kubernetes namespace for the Istio deployment.
ISTIO_VERSION: The version of Istio to be used.
- The path to the Istio operator configuration YAML file.
- The Kubernetes namespace for the Istio deployment.
- The version of Istio to be used.

Copy link
Author

Choose a reason for hiding this comment

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

Done modified readme

docs/README.md Outdated
@@ -303,6 +303,25 @@ Note the quotes around the value of `spec.values.pilot.env.PILOT_ENABLE_STATUS`.

Sail Operator's Istio resource does not have a `spec.components` field. Instead, you can enable and disable components directly by setting `spec.values.<component>.enabled: true/false`. Other functionality exposed through `spec.components` like the k8s overlays is not currently available.

### Converter Script
This script is used to convert an Istio in-cluster operator configuration to a Sail Operator configuration. Upon execution, a new YAML file will be created in the same directory which ISTIO-OPERATOR-CONFIG-YAML is present. The new file will be named: sail-operator-config.yaml
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
This script is used to convert an Istio in-cluster operator configuration to a Sail Operator configuration. Upon execution, a new YAML file will be created in the same directory which ISTIO-OPERATOR-CONFIG-YAML is present. The new file will be named: sail-operator-config.yaml
This script is used to convert an Istio in-cluster operator configuration to a Sail Operator configuration. Upon execution, a new YAML file will be created in the same directory as the source YAML file. The new file will be named: sail-operator-config.yaml

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, wouldn't it be better to generate the new file name from the original file name, and just adding sail.yaml as the suffix? If someone has multiple files to convert, it would be a hassle to have to rename the output file every time. And if they don't rename it, the file gets overwritten; what if the person doesn't notice?

Copy link
Author

Choose a reason for hiding this comment

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

Done. added an optional argument for output file. If not present it will add -sail.yaml suffix to input file

var (
controlPlaneNamespace = "istio-system"
// Test converter with latest istio version
istioVersion = supportedversion.List[len(supportedversion.List)-1].Name
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe there's a supportedversion.Default or something like that? No need to get the version from the list.

Copy link
Author

Choose a reason for hiding this comment

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

Done

func TestSimpleYamlConversion(t *testing.T) {
g := NewWithT(t)

istioYamlText := `apiVersion: install.istio.io/v1alpha1
Copy link
Contributor

Choose a reason for hiding this comment

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

Can rename this to istioYaml. Same for sailYamlText. Shorter names are usually better, especially if the variable's context is very small. It makes reading the code faster.

Copy link
Author

Choose a reason for hiding this comment

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

Done

Comment on lines 62 to 65
err = os.Remove(filepath.Join(project.RootDir, "tools", "istioConfig.yaml"))
g.Expect(err).To(Succeed(), "Unable to delete istioConfig.yaml")
err = os.Remove(filepath.Join(project.RootDir, "tools", "sail-operator-config.yaml"))
g.Expect(err).To(Succeed(), "Unable to delete sail-operator-config.yaml")
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this get executed if the assertions above fail?

Copy link
Author

Choose a reason for hiding this comment

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

Added a cleanup function for removing created files.


g.Expect(executeConfigConverter(istioYamlFileWithPath, controlPlaneNamespace, istioVersion)).To(Succeed(),
"error in execution of ./configuration-converter.sh")
isConversionValidated, err := validateYamlContent(sailYamlText)
Copy link
Contributor

Choose a reason for hiding this comment

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

One thing I don't like about the validateYamlContent function is that it isn't clear what it's comparing to the sailYamlText. It would be clearer if you passed in both YAMLs. Then, when someone sees validateYamlContent(actual, expected), it would immediately clear what the function is doing. Right now, seeing this function causes confusion.

Copy link
Author

Choose a reason for hiding this comment

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

Done

@@ -53,3 +54,34 @@ func ExecuteShell(command string, input string) (string, error) {

return stdout.String(), nil
}

// Execute bash script with optional arguments
func ExecuteBashScript(scriptPath string, args ...string) (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need this function? Doesn't ExecuteShell have everything we need already?

Copy link
Author

Choose a reason for hiding this comment

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

Done. removed function

ISTIO_NAMESPACE="$3"
SAIL_CONFIG_FILE="sail-operator-config.yaml"

cp "$WORKDIR"/"$ISTIO_CONFIG_FILE" "$SAIL_CONFIG_FILE" || exit 1
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd move this after the functions. Currently, we copy the file here, but then modify it in a totally different place in the script. It would be best to keep all the steps together, possibly even in a function that is then called at the end of the script.

Copy link
Author

Choose a reason for hiding this comment

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

Done

validate_spec_components
fi

chmod +x $SAIL_CONFIG_FILE
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this really necessary?

Copy link
Author

Choose a reason for hiding this comment

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

It is to be able to use created yaml in oc/kubectl command afterwards. oc apply -f sail-config.yaml

Copy link
Author

Choose a reason for hiding this comment

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

Done. removed command since I couldn't reproduce the error.


chmod +x $SAIL_CONFIG_FILE

if ! mv "$SAIL_CONFIG_FILE" "$WORKDIR" 2>&1 | grep -q "are identical"; then
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it a good idea to assume what the output text can be?

Copy link
Author

Choose a reason for hiding this comment

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

Removed after adding output as argument

docs/README.md Outdated
```bash
./tools/configuration-converter.sh tools/istio_config.yaml istio-system v1.24.3
./tools/configuration-converter.sh -i /home/user/input/istio_config.yaml -o /home/user/output/output.yaml -n custom-namespace -v v1.24.3
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to have to specify -i instead of just the file name? You always need to specify the input file, so why make the user type -i? Similar for -o, even though that one is optional. The input and output seem like the most important arguments, so we don't need to specify them via flags. The namespace and version arguments are not at the same level (much more optional than the output file), so it makes sense to set them via flags.

Copy link
Author

Choose a reason for hiding this comment

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

Done. I have removed -i and -o arguments and updated readme

@ctartici
Copy link
Author

/retest

@ctartici ctartici force-pushed the main branch 6 times, most recently from 1daa88c to f0c5825 Compare February 13, 2025 12:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants